1  /-
  2  Copyright (c) 2018 Chris Hughes. All rights reserved.
  3  Released under Apache 2.0 license as described in the file LICENSE.
  4  Authors: Chris Hughes, Johannes Hölzl, Jens Wagemaker
  5  
  6  Theory of univariate polynomials, represented as `ℕ →₀ α`, where α is a commutative semiring.
  7  -/
  8  import data.finsupp algebra.gcd_domain ring_theory.euclidean_domain tactic.ring_exp ring_theory.multiplicity
src         └──────────┘ └────────────────┘ └──────────────────────────┘ └─────────────┘ └──────────────────────┘
  9  
 10  noncomputable theory
 11  local attribute [instance, priority 100] classical.prop_decidable
id                                            └──────────────────────┘
src                                           └──────────────────────┘
typ                                           └──────────────────────┘
 12  
 13  /-- `polynomial α` is the type of univariate polynomials over `α`.
 14  
 15  Polynomials should be seen as (semi-)rings with the additional constructor `X`.
 16  The embedding from α is called `C`. -/
 17  def polynomial (α : Type*) [comm_semiring α] := ℕ →₀ α
id                               └───────────┘       └┘ 
src                              └───────────┘        └┘
typ                              └───────────┘       └┘ 
doc                                                    └┘
 18  
 19  open finsupp finset lattice
 20  
 21  namespace polynomial
 22  universes u v
 23  variables {α : Type u} {β : Type v} {a b : α} {m n : ℕ}
id                                                        
src                                                       
typ                                                       
 24  
 25  section comm_semiring
 26  variables [comm_semiring α] {p q r : polynomial α}
id              └───────────┘             └────────┘
src             └───────────┘             └────────┘
typ             └───────────┘             └────────┘
doc                                       └────────┘
 27  
 28  instance : inhabited (polynomial α) := finsupp.inhabited
id              └───────┘  └────────┘      └───────────────┘
src             └───────┘  └────────┘       └───────────────┘
typ             └───────┘  └────────┘      └───────────────┘
doc                        └────────┘
 29  instance : has_zero (polynomial α) := finsupp.has_zero
id              └──────┘  └────────┘      └──────────────┘
src             └──────┘  └────────┘       └──────────────┘
typ             └──────┘  └────────┘      └──────────────┘
doc                       └────────┘
 30  instance : has_one (polynomial α) := finsupp.has_one
id              └─────┘  └────────┘      └─────────────┘
src             └─────┘  └────────┘       └─────────────┘
typ             └─────┘  └────────┘      └─────────────┘
doc                      └────────┘       └─────────────┘
 31  instance : has_add (polynomial α) := finsupp.has_add
id              └─────┘  └────────┘      └─────────────┘
src             └─────┘  └────────┘       └─────────────┘
typ             └─────┘  └────────┘      └─────────────┘
doc                      └────────┘
 32  instance : has_mul (polynomial α) := finsupp.has_mul
id              └─────┘  └────────┘      └─────────────┘
src             └─────┘  └────────┘       └─────────────┘
typ             └─────┘  └────────┘      └─────────────┘
doc                      └────────┘       └─────────────┘
 33  instance : comm_semiring (polynomial α) := finsupp.comm_semiring
id              └───────────┘  └────────┘      └───────────────────┘
src             └───────────┘  └────────┘       └───────────────────┘
typ             └───────────┘  └────────┘      └───────────────────┘
doc                            └────────┘
 34  
 35  def coeff_coe_to_fun : has_coe_to_fun (polynomial α) :=
id                          └────────────┘  └────────┘ 
src                         └────────────┘  └────────┘
typ                         └────────────┘  └────────┘ 
doc                                         └────────┘
 36  finsupp.has_coe_to_fun
id   └────────────────────┘
src  └────────────────────┘
typ  └────────────────────┘
 37  
 38  local attribute [instance] finsupp.comm_semiring coeff_coe_to_fun
id                              └───────────────────┘ └──────────────┘
src                             └───────────────────┘ └──────────────┘
typ                             └───────────────────┘ └──────────────┘
 39  
 40  @[simp] lemma support_zero : (0 : polynomial α).support = ∅ := rfl
id                                     └────────┘  └─────┘       └─┘
src                                    └────────┘   └─────┘       └─┘
typ                                    └────────┘  └─────┘       └─┘
doc    └──┘                            └────────┘
 41  
 42  /-- `C a` is the constant polynomial `a`. -/
 43  def C (a : α) : polynomial α := single 0 a
id                  └────────┘     └────┘   
src                  └────────┘      └────┘
typ                 └────────┘     └────┘   
doc                  └────────┘      └────┘
 44  
 45  /-- `X` is the polynomial variable (aka indeterminant). -/
 46  def X : polynomial α := single 1 1
id           └────────┘     └────┘
src          └────────┘      └────┘
typ          └────────┘     └────┘
doc          └────────┘      └────┘
 47  
 48  /-- coeff p n is the coefficient of X^n in p -/
 49  def coeff (p : polynomial α) := p.to_fun
id                  └────────┘      └─────┘
src                 └────────┘        └─────┘
typ                 └────────┘      └─────┘
doc                 └────────┘
 50  
 51  @[simp] lemma coeff_mk (s) (f) (h) : coeff (finsupp.mk s f h : polynomial α) = f := rfl
id                                        └───┘  └────────┘      └────────┘        └─┘
src                                       └───┘  └────────┘         └────────┘          └─┘
typ                                       └───┘  └────────┘      └────────┘        └─┘
doc    └──┘                               └───┘                     └────────┘
 52  
 53  instance [has_repr α] : has_repr (polynomial α) :=
id             └──────┘     └──────┘  └────────┘ 
src            └──────┘      └──────┘  └────────┘
typ            └──────┘     └──────┘  └────────┘ 
doc                                    └────────┘
 54  ⟨λ p, if p = 0 then "0"
id            
src             
typ           
 55    else (p.support.sort (≤)).foldr
id           └──────┘└───┘    └───┘
src           └──────┘└───┘    └───┘
typ          └──────┘└───┘    └───┘
doc                   └───┘
 56      (λ n a, a ++ (if a = "" then "" else " + ") ++
id              └┘                              └┘
src                └┘                               └┘
typ             └┘                              └┘
 57        if n = 0
id             
src             
typ            
 58          then "C (" ++ repr (coeff p n) ++ ")"
id                      └┘ └──┘  └───┘    └┘
src                     └┘ └──┘  └───┘      └┘
typ                     └┘ └──┘  └───┘    └┘
doc                              └───┘
 59          else if n = 1
id                    
src                    
typ                   
 60            then if (coeff p n) = 1 then "X" else "C (" ++ repr (coeff p n) ++ ") * X"
id                      └───┘                           └┘ └──┘  └───┘    └┘
src                     └───┘                             └┘ └──┘  └───┘      └┘
typ                     └───┘                           └┘ └──┘  └───┘    └┘
doc                     └───┘                                       └───┘
 61            else if (coeff p n) = 1 then "X ^ " ++ repr n
id                      └───┘                   └┘ └──┘ 
src                     └───┘                     └┘ └──┘
typ                     └───┘                   └┘ └──┘ 
doc                     └───┘
 62              else "C (" ++ repr (coeff p n) ++ ") * X ^ " ++ repr n) ""⟩
id                          └┘ └──┘  └───┘    └┘            └┘ └──┘ 
src                         └┘ └──┘  └───┘      └┘            └┘ └──┘
typ                         └┘ └──┘  └───┘    └┘            └┘ └──┘ 
doc                                  └───┘
 63  
 64  theorem ext_iff {p q : polynomial α} : p = q ↔ ∀ n, coeff p n = coeff q n :=
id                          └────────┘             └───┘    └───┘  
src                         └────────┘                 └───┘      └───┘
typ                         └────────┘             └───┘    └───┘  
doc                         └────────┘                   └───┘       └───┘
 65  ⟨λ h n, h ▸ rfl, finsupp.ext⟩
id           └─┘  └─────────┘
src             └─┘  └─────────┘
typ          └─┘  └─────────┘
 66  
 67  @[ext] lemma ext {p q : polynomial α} : (∀ n, coeff p n = coeff q n) → p = q :=
id                           └────────┘          └───┘    └───┘        
src                          └────────┘            └───┘      └───┘          
typ                          └────────┘          └───┘    └───┘        
doc    └─┘                   └────────┘            └───┘       └───┘
 68  (@ext_iff _ _ p q).2
id     └─────┘       
src    └─────┘         
typ    └─────┘       
 69  
 70  /-- `degree p` is the degree of the polynomial `p`, i.e. the largest `X`-exponent in `p`.
 71  `degree p = some n` when `p ≠ 0` and `n` is the highest power of `X` that appears in `p`, otherwise
 72  `degree 0 = ⊥`. -/
 73  def degree (p : polynomial α) : with_bot ℕ := p.support.sup some
id                   └────────┘     └──────┘     └──────┘└──┘ └──┘
src                  └────────┘      └──────┘      └──────┘└──┘ └──┘
typ                  └────────┘     └──────┘     └──────┘└──┘ └──┘
doc                  └────────┘                             └──┘
 74  
 75  lemma degree_lt_wf : well_founded (λp q : polynomial α, degree p < degree q) :=
id                        └──────────┘         └────────┘   └────┘   └────┘ 
src                       └──────────┘         └────────┘    └────┘    └────┘
typ                       └──────────┘         └────────┘   └────┘   └────┘ 
doc                                            └────────┘    └────┘     └────┘
 76  inv_image.wf degree (with_bot.well_founded_lt nat.lt_wf)
id   └──────────┘ └────┘  └──────────────────────┘ └───────┘
src  └──────────┘ └────┘  └──────────────────────┘ └───────┘
typ  └──────────┘ └────┘  └──────────────────────┘ └───────┘
doc               └────┘
 77  
 78  instance : has_well_founded (polynomial α) := ⟨_, degree_lt_wf⟩
id              └──────────────┘  └────────┘          └──────────┘
src             └──────────────┘  └────────┘           └──────────┘
typ             └──────────────┘  └────────┘          └──────────┘
doc                               └────────┘
 79  
 80  /-- `nat_degree p` forces `degree p` to ℕ, by defining nat_degree 0 = 0. -/
 81  def nat_degree (p : polynomial α) : ℕ := (degree p).get_or_else 0
id                       └────────┘          └────┘  └─────────┘
src                      └────────┘           └────┘   └─────────┘
typ                      └────────┘          └────┘  └─────────┘
doc                      └────────┘            └────┘
 82  
 83  lemma single_eq_C_mul_X : ∀{n}, single n a = C a * X^n
id                                 └────┘       
src                                  └────┘          
typ                                └────┘       
doc                                  └────┘            
 84  | 0     := (mul_one _).symm
id               └─────┘   └──┘
src              └─────┘   └──┘
typ              └─────┘   └──┘
 85  | (n+1) :=
id      
src      
typ     
 86    calc single (n + 1) a = single n a * X : by rw [X, single_mul_single, mul_one]
id          └────┘           └────┘                 └───────────────┘  └─────┘
src         └────┘            └────┘            └──┘└┘└───────────────┘└┘└─────┘└─
typ         └────┘           └────┘           └──┘└┘└───────────────┘└┘└─────┘└─
doc         └────┘             └────┘             └──┘└┘                 └┘       └─
txt                                                └──┘ └┘                 └┘       └─
par                                                └──┘ └┘                 └┘       └─
pid                                                  └┘ └┘                 └┘       
st                                                └────┘└─────────────────┘└───────┘
 87      ... = (C a * X^n) * X : by rw [single_eq_C_mul_X]
id                     
src  ───┘                     └──┘                 └─
typ  ───┘                    └──┘└───────────────┘└─
doc  ───┘                        └──┘                 └─
txt  ───┘                           └──┘                 └─
par  ───┘                           └──┘                 └─
pid  ───┘                             └┘                 
st   ───┘                          └────────────────────┘
 88      ... = C a * X^(n+1) : by simp only [pow_add, mul_assoc, pow_one]
id                                     └─────┘  └───────┘  └─────┘
src  ───┘                    └─────────┘└─────┘└┘└───────┘└┘└─────┘└─
typ  ───┘                   └─────────┘└─────┘└┘└───────┘└┘└─────┘└─
doc  ───┘                       └─────────┘       └┘         └┘       └─
txt  ───┘                         └─────────┘       └┘         └┘       └─
par  ───┘                         └─────────┘       └┘         └┘       └─
pid  ───┘                             └──┘└┘       └┘         └┘       
st   ───┘                        └────────────────────────────────────────
 89  
src  
typ  
doc  
txt  
par  
pid  
st   
 90  lemma sum_C_mul_X_eq (p : polynomial α) : p.sum (λn a, C a * X^n) = p :=
id                             └────────┘     └──┘            
src                            └────────┘       └──┘               
typ                            └────────┘     └──┘            
doc                            └────────┘       └──┘             
 91  eq.trans (sum_congr rfl $ assume n hn, single_eq_C_mul_X.symm) (finsupp.sum_single _)
id   └──────┘  └───────┘ └─┘           └┘  └───────────────┘└───┘   └────────────────┘
src  └──────┘  └───────┘ └─┘                └───────────────┘└───┘   └────────────────┘
typ  └──────┘  └───────┘ └─┘           └┘  └───────────────┘└───┘   └────────────────┘
 92  
 93  @[elab_as_eliminator] protected lemma induction_on {M : polynomial α → Prop} (p : polynomial α)
id                                                           └────────┘               └────────┘ 
src                                                          └────────┘                └────────┘
typ                                                          └────────┘               └────────┘ 
doc    └────────────────┘                                    └────────┘                └────────┘
 94    (h_C : ∀a, M (C a))
id                  
src                  
typ                 
doc                  
 95    (h_add : ∀p q, M p → M q → M (p + q))
id                              
src                                    
typ                             
 96    (h_monomial : ∀(n : ℕ) (a : α), M (C a * X^n) → M (C a * X^(n+1))) :
id                                                  
src                                                        
typ                                                 
doc                                                          
 97    M p :=
id      
typ     
 98  have ∀{n:ℕ} {a}, M (C a * X^n),
id                       
src                         
typ                      
doc                           
 99  begin
st   └─────
100    assume n a,
src    └────────┘
typ    └────────┘
doc    └────────┘
txt    └────────┘
par    └────────┘
pid    └────────┘
st   ───────────┘└─
101    induction n with n ih,
id               
src    └────────┘ └────────┘
typ    └────────┘└────────┘
doc    └────────┘ └────────┘
txt    └────────┘ └────────┘
par    └────────┘ └────────┘
pid              └───────┘
st   ──────────────────────┘└─
102    { simp only [pow_zero, mul_one, h_C] },
id                  └──────┘  └─────┘  └─┘
src      └─────────┘└──────┘└┘└─────┘└┘   └┘
typ      └─────────┘└──────┘└┘└─────┘└┘└─┘└┘
doc      └─────────┘        └┘       └┘   └┘
txt      └─────────┘        └┘       └┘   └┘
par      └─────────┘        └┘       └┘   └┘
pid          └──┘└┘        └┘       └┘   
st   ───┘└─────────────────────────────────┘└┘
103    { exact h_monomial _ _ ih }
id             └────────┘     └┘
src      └────┘          └───┘  
typ      └────┘└────────┘└───┘└┘
doc      └────┘          └───┘  
txt      └────┘          └───┘  
par      └────┘          └───┘  
pid                     └───┘  
st   ───────────────────────────┘└─
104  end,
st   ──┘
105  finsupp.induction p
id   └───────────────┘ 
src  └───────────────┘
typ  └───────────────┘ 
106    (suffices M (C 0), by simpa only [C, single_zero],
id                                       └─────────┘
src                         └──────────┘└┘└─────────┘
typ                        └──────────┘└┘└─────────┘
doc                         └──────────┘└┘           
txt                          └──────────┘ └┘           
par                          └──────────┘ └┘           
pid                               └──┘└┘ └┘           
st                          └──────────────────────────┘
107      h_C 0)
id       └─┘
typ      └─┘
108    (assume n a p _ _ hp, suffices M (C a * X^n + p), by rwa [single_eq_C_mul_X],
id                  └┘                             └───────────────┘
src                                                    └───┘└───────────────┘
typ                 └┘                        └───┘└───────────────┘
doc                                                       └───┘                 
txt                                                         └───┘                 
par                                                         └───┘                 
pid                                                            └┘                 
st                                                         └─────────────────────┘
109      h_add _ _ this hp)
id       └───┘     └──┘ └┘
typ      └───┘     └──┘ └┘
110  
111  @[simp] lemma C_0 : C (0 : α) = 0 := single_zero
id                                     └─────────┘
src                                     └─────────┘
typ                                    └─────────┘
doc    └──┘              
112  
113  @[simp] lemma C_1 : C (1 : α) = 1 := rfl
id                                     └─┘
src                                     └─┘
typ                                    └─┘
doc    └──┘              
114  
115  @[simp] lemma C_mul : C (a * b) = C a * C b :=
id                                    
src                                     
typ                                   
doc    └──┘                                
116  (@single_mul_single _ _ _ _ 0 0 a b).symm
id     └───────────────┘               └──┘
src    └───────────────┘                 └──┘
typ    └───────────────┘               └──┘
117  
118  @[simp] lemma C_add : C (a + b) = C a + C b := finsupp.single_add
id                                        └────────────────┘
src                                           └────────────────┘
typ                                       └────────────────┘
doc    └──┘                                
119  
120  instance C.is_semiring_hom : is_semiring_hom (C : α → polynomial α) :=
id                                └─────────────┘        └────────┘ 
src                               └─────────────┘         └────────┘
typ                               └─────────────┘        └────────┘ 
doc                               └─────────────┘         └────────┘
121  ⟨C_0, C_1, λ _ _, C_add, λ _ _, C_mul⟩
id    └─┘  └─┘       └───┘       └───┘
src   └─┘  └─┘         └───┘         └───┘
typ   └─┘  └─┘       └───┘       └───┘
122  
123  @[simp] lemma C_pow : C (a ^ n) = C a ^ n := is_semiring_hom.map_pow _ _ _
id                                       └─────────────────────┘
src                                          └─────────────────────┘
typ                                      └─────────────────────┘
doc    └──┘                           
124  
125  lemma nat_cast_eq_C (n : ℕ) : (n : polynomial α) = C n :=
id                                    └────────┘     
src                                    └────────┘     
typ                                   └────────┘     
doc                                     └────────┘      
126  by refine (nat.eq_cast (λ n, C (n : α)) _ _ _ n).symm; simp
id              └─────────┘                      
src     └─────┘ └─────────┘  └──┘  └─┘ └───────┘ └────┘  └────
typ     └─────┘ └─────────┘  └──┘  └─┘└───────┘└────┘  └────
doc     └─────┘              └──┘  └─┘ └───────┘ └────┘  └────
txt     └─────┘              └──┘   └─┘ └───────┘ └────┘  └────
par     └─────┘              └──┘   └─┘ └───────┘ └────┘  └────
pid                         └──┘   └─┘ └───────┘ └───┘      
st     └─────────────────────────────────────────────────────────
127  
src  
typ  
doc  
txt  
par  
pid  
st   
128  section coeff
129  
130  lemma apply_eq_coeff : p n = coeff p n := rfl
id                             └───┘      └─┘
src                              └───┘        └─┘
typ                            └───┘      └─┘
doc                               └───┘
131  
132  @[simp] lemma coeff_zero (n : ℕ) : coeff (0 : polynomial α) n = 0 := rfl
id                                     └───┘      └────────┘          └─┘
src                                    └───┘      └────────┘            └─┘
typ                                    └───┘      └────────┘          └─┘
doc    └──┘                             └───┘      └────────┘
133  
134  lemma coeff_single : coeff (single n a) m = if n = m then a else 0 :=
id                        └───┘  └────┘                 
src                       └───┘  └────┘              
typ                       └───┘  └────┘                 
doc                       └───┘  └────┘
135  by { dsimp [single], congr }
id               └────┘
src       └─────┘└────┘  └────┘
typ       └─────┘└────┘  └────┘
doc       └─────┘└────┘
txt       └─────┘        └────┘
par       └─────┘        └────┘
pid                         
st     └───────────────┘└──────┘└┘
136  
137  @[simp] lemma coeff_one_zero : coeff (1 : polynomial α) 0 = 1 :=
id                                  └───┘      └────────┘     
src                                 └───┘      └────────┘      
typ                                 └───┘      └────────┘     
doc    └──┘                         └───┘      └────────┘
138  coeff_single
id   └──────────┘
src  └──────────┘
typ  └──────────┘
139  
140  @[simp] lemma coeff_add (p q : polynomial α) (n : ℕ) : coeff (p + q) n = coeff p n + coeff q n := rfl
id                                  └────────┘            └───┘        └───┘    └───┘      └─┘
src                                 └────────┘             └───┘           └───┘      └───┘        └─┘
typ                                 └────────┘            └───┘        └───┘    └───┘      └─┘
doc    └──┘                         └────────┘              └───┘             └───┘       └───┘
141  
142  instance coeff.is_add_monoid_hom {n : ℕ} : is_add_monoid_hom (λ p : polynomial α, p.coeff n) :=
id                                             └───────────────┘        └────────┘   └────┘ 
src                                            └───────────────┘        └────────┘     └────┘
typ                                            └───────────────┘        └────────┘   └────┘ 
doc                                             └───────────────┘        └────────┘     └────┘
143  { map_add  := λ p q, coeff_add p q n,
id                      └───────┘   
src                       └───────┘
typ                     └───────┘   
144    map_zero := coeff_zero _ }
id                 └────────┘
src                └────────┘
typ                └────────┘
145  
146  lemma coeff_C : coeff (C a) n = ite (n = 0) a 0 :=
id                   └───┘       └─┘       
src                  └───┘         └─┘    
typ                  └───┘       └─┘       
doc                  └───┘  
147  by simp [coeff, eq_comm, C, single]; congr
id            └───┘  └─────┘    └────┘
src     └────┘└───┘└┘└─────┘└┘└┘└────┘  └─────
typ     └────┘└───┘└┘└─────┘└┘└┘└────┘  └─────
doc     └────┘└───┘└┘       └┘└┘└────┘
txt     └────┘     └┘       └┘ └┘        └─────
par     └────┘     └┘       └┘ └┘        └─────
pid              └┘       └┘ └┘             
st     └────────────────────────────────────────
148  
src  
typ  
txt  
par  
pid  
st   
149  @[simp] lemma coeff_C_zero : coeff (C a) 0 = a := coeff_single
id                                └───┘            └──────────┘
src                               └───┘              └──────────┘
typ                               └───┘            └──────────┘
doc    └──┘                       └───┘  
150  
151  @[simp] lemma coeff_X_one : coeff (X : polynomial α) 1 = 1 := coeff_single
id                               └───┘     └────────┘           └──────────┘
src                              └───┘     └────────┘            └──────────┘
typ                              └───┘     └────────┘           └──────────┘
doc    └──┘                      └───┘     └────────┘
152  
153  @[simp] lemma coeff_X_zero : coeff (X : polynomial α) 0 = 0 := coeff_single
id                                └───┘     └────────┘           └──────────┘
src                               └───┘     └────────┘            └──────────┘
typ                               └───┘     └────────┘           └──────────┘
doc    └──┘                       └───┘     └────────┘
154  
155  lemma coeff_X : coeff (X : polynomial α) n = if 1 = n then 1 else 0 := coeff_single
id                   └───┘     └────────┘                             └──────────┘
src                  └───┘     └────────┘                                └──────────┘
typ                  └───┘     └────────┘                             └──────────┘
doc                  └───┘     └────────┘
156  
157  @[simp] lemma coeff_C_mul_X (x : α) (k n : ℕ) :
id                                             
src                                             
typ                                            
doc    └──┘
158    coeff (C x * X^k : polynomial α) n = if n = k then x else 0 :=
id     └───┘        └────────┘                
src    └───┘          └────────┘            
typ    └───┘        └────────┘                
doc    └───┘            └────────┘
159  by rw [← single_eq_C_mul_X]; simp [single, eq_comm, coeff]; congr
id            └───────────────┘         └────┘  └─────┘  └───┘
src     └────┘└───────────────┘  └────┘└────┘└┘└─────┘└┘└───┘  └─────
typ     └────┘└───────────────┘  └────┘└────┘└┘└─────┘└┘└───┘  └─────
doc     └────┘                   └────┘└────┘└┘       └┘└───┘
txt     └────┘                   └────┘      └┘       └┘       └─────
par     └────┘                   └────┘      └┘       └┘       └─────
pid       └──┘                             └┘       └┘            
st     └──────────────────────┘└──────────────────────────────────────
160  
src  
typ  
txt  
par  
pid  
st   
161  lemma coeff_sum [comm_semiring β] (n : ℕ) (f : ℕ → α → polynomial β) :
id                    └───────────┘                     └────────┘ 
src                   └───────────┘                       └────────┘
typ                   └───────────┘                     └────────┘ 
doc                                                         └────────┘
162    coeff (p.sum f) n = p.sum (λ a b, coeff (f a b) n) := finsupp.sum_apply
id     └───┘  └──┘     └──┘       └───┘           └───────────────┘
src    └───┘   └──┘        └──┘         └───┘               └───────────────┘
typ    └───┘  └──┘     └──┘       └───┘           └───────────────┘
doc    └───┘   └──┘         └──┘         └───┘
163  
164  @[simp] lemma coeff_C_mul (p : polynomial α) : coeff (C a * p) n = a * coeff p n :=
id                                  └────────┘     └───┘           └───┘  
src                                 └────────┘      └───┘               └───┘
typ                                 └────────┘     └───┘           └───┘  
doc    └──┘                         └────────┘      └───┘                  └───┘
165  begin
st   └─────
166    conv in (a * _) { rw [← @sum_single _ _ _ p, coeff_sum] },
id                            └────────┘         └───────┘
src    └──────┘  └────┘└────┘ └────────┘└─────┘ └┘└───────┘└┘
typ    └──────┘ └────┘└────┘ └────────┘└─────┘└┘└───────┘└┘
txt    └──────┘   └────┘└────┘           └─────┘ └┘         └┘
par    └──────┘   └────┘└────┘           └─────┘ └┘         └┘
pid        └─┘   └─┘└───────┘           └─────┘ └┘         └─┘
st   ──────────────────┘└────────────────────────┘└─────────┘ └┘
167    rw [mul_def, C, sum_single_index],
id         └─────┘    └──────────────┘
src    └──┘└─────┘└┘└┘└──────────────┘
typ    └──┘└─────┘└┘└┘└──────────────┘
doc    └──┘       └┘└┘                
txt    └──┘       └┘ └┘                
par    └──┘       └┘ └┘                
pid      └┘       └┘ └┘                
st   ────────────┘└─┘└────────────────┘└──
168    { simp [coeff_single, finsupp.mul_sum, coeff_sum],
id             └──────────┘  └─────────────┘  └───────┘
src      └────┘└──────────┘└┘└─────────────┘└┘└───────┘
typ      └────┘└──────────┘└┘└─────────────┘└┘└───────┘
doc      └────┘            └┘               └┘         
txt      └────┘            └┘               └┘         
par      └────┘            └┘               └┘         
pid                      └┘               └┘         
st   ───┘└─────────────────────────────────────────────┘└─
169      apply sum_congr rfl,
id             └───────┘ └─┘
src      └────┘└───────┘└─┘
typ      └────┘└───────┘└─┘
doc      └────┘         
txt      └────┘         
par      └────┘         
pid                    
st   ──────────────────────┘└─
170      assume i hi, by_cases i = n; simp [h] },
id                                       
src      └─────────┘  └───────┘    └────┘ └┘
typ      └─────────┘  └───────┘  └────┘└┘
doc      └─────────┘  └───────┘     └────┘ └┘
txt      └─────────┘  └───────┘     └────┘ └┘
par      └─────────┘  └───────┘     └────┘ └┘
pid      └─────────┘                    
st   ──────────────┘└─────────────────────────┘└┘
171    simp
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
pid        
st   ──────┘
172  end
st   └─┘
173  
174  @[simp] lemma coeff_one (n : ℕ) : coeff (1 : polynomial α) n = if 0 = n then 1 else 0 :=
id                                    └───┘      └────────┘           
src                                   └───┘      └────────┘            
typ                                   └───┘      └────────┘           
doc    └──┘                            └───┘      └────────┘
175  coeff_single
id   └──────────┘
src  └──────────┘
typ  └──────────┘
176  
177  @[simp] lemma coeff_X_pow (k n : ℕ) :
id                                    
src                                   
typ                                   
doc    └──┘
178    coeff (X^k : polynomial α) n = if n = k then 1 else 0 :=
id     └───┘     └────────┘          
src    └───┘      └────────┘            
typ    └───┘     └────────┘          
doc    └───┘       └────────┘
179  by simpa only [C_1, one_mul] using coeff_C_mul_X (1:α) k n
id                  └─┘  └─────┘        └───────────┘       
src     └──────────┘└─┘└┘└─────┘└──────┘└───────────┘ └┘ └┘  
typ     └──────────┘└─┘└┘└─────┘└──────┘└───────────┘ └┘└┘
doc     └──────────┘   └┘       └──────┘              └┘ └┘  
txt     └──────────┘   └┘       └──────┘              └┘ └┘  
par     └──────────┘   └┘       └──────┘              └┘ └┘  
pid          └──┘└┘   └┘       └────┘              └┘ └┘  
st     └────────────────────────────────────────────────────────
180  
src  
typ  
doc  
txt  
par  
pid  
st   
181  lemma coeff_mul (p q : polynomial α) (n : ℕ) :
id                          └────────┘        
src                         └────────┘         
typ                         └────────┘        
doc                         └────────┘
182    coeff (p * q) n = (nat.antidiagonal n).sum (λ x, coeff p x.1 * coeff q x.2) :=
id     └───┘         └──────────────┘  └─┘       └───┘     └───┘  
src    └───┘            └──────────────┘   └─┘        └───┘       └───┘    
typ    └───┘         └──────────────┘  └─┘       └───┘     └───┘  
doc    └───┘              └──────────────┘              └───┘         └───┘
183  have hite : ∀ a : ℕ × ℕ, ite (a.1 + a.2 = n) (coeff p (a.fst) * coeff q (a.snd)) 0 ≠ 0
id                         └─┘           └───┘   └──┘   └───┘   └──┘     
src                        └─┘              └───┘     └──┘   └───┘     └──┘     
typ                        └─┘           └───┘   └──┘   └───┘   └──┘     
doc                                                └───┘             └───┘
184      → a.1 + a.2 = n, from λ a ha, by_contradiction
id                         └┘  └──────────────┘
src                                └──────────────┘
typ                        └┘  └──────────────┘
185    (λ h, absurd (eq.refl (0 : α)) (by rwa if_neg h at ha)),
id          └────┘  └─────┘                 └────┘ 
src          └────┘  └─────┘              └──┘└────┘ └────┘
typ         └────┘  └─────┘             └──┘└────┘└────┘
doc                                       └──┘       └────┘
txt                                       └──┘       └────┘
par                                       └──┘       └────┘
pid                                                 └────┘
st                                       └─────────────────┘
186  calc coeff (p * q) n = sum (p.support) (λ a, sum (q.support)
id        └───┘         └─┘  └──────┘       └─┘  └──────┘
src       └───┘            └─┘   └──────┘        └─┘   └──────┘
typ       └───┘         └─┘  └──────┘       └─┘  └──────┘
doc       └───┘
187      (λ b, ite (a + b = n) (coeff p a * coeff q b) 0)) :
id            └─┘         └───┘    └───┘  
src            └─┘            └───┘      └───┘
typ           └─┘         └───┘    └───┘  
doc                             └───┘       └───┘
188    by simp only [finsupp.mul_def, coeff_sum, coeff_single]; refl
id                   └─────────────┘  └───────┘  └──────────┘
src       └─────────┘└─────────────┘└┘└───────┘└┘└──────────┘  └───┘
typ       └─────────┘└─────────────┘└┘└───────┘└┘└──────────┘  └───┘
doc       └─────────┘               └┘         └┘              └───┘
txt       └─────────┘               └┘         └┘              └───┘
par       └─────────┘               └┘         └┘              └───┘
pid           └──┘└┘               └┘         └┘                  
st       └──────────────────────────────────────────────────────────┘
189  ... = (p.support.product q.support).sum
id          └──────┘└──────┘ └──────┘ └─┘
src          └──────┘└──────┘  └──────┘ └─┘
typ         └──────┘└──────┘ └──────┘ └─┘
doc                  └──────┘
190      (λ v : ℕ × ℕ, ite (v.1 + v.2 = n) (coeff p v.1 * coeff q v.2) 0) :
id                  └─┘           └───┘     └───┘  
src                 └─┘              └───┘       └───┘    
typ                 └─┘           └───┘     └───┘  
doc                                         └───┘         └───┘
191    by rw sum_product
id           └─────────┘
src       └─┘└─────────┘
typ       └─┘└─────────┘
doc       └─┘           
txt       └─┘           
par       └─┘           
pid                    
st       └──────────────┘
192  ... = (nat.antidiagonal n).sum (λ x, coeff p x.1 * coeff q x.2) :
id          └──────────────┘  └─┘       └───┘     └───┘  
src         └──────────────┘   └─┘        └───┘       └───┘    
typ         └──────────────┘  └─┘       └───┘     └───┘  
doc         └──────────────┘              └───┘         └───┘
193  begin
st   └─────
194    refine sum_bij_ne_zero (λ x _ _, x)
id            └─────────────┘
src    └─────┘└─────────────┘  └──────┘ └─
typ    └─────┘└─────────────┘  └──────┘ └─
doc    └─────┘                 └──────┘ └─
txt    └─────┘                 └──────┘ └─
par    └─────┘                 └──────┘ └─
pid                           └──────┘ └─
st   ──────────────────────────────────────
195    (λ x _ hx, nat.mem_antidiagonal.2 (hite x hx)) (λ _ _ _ _ _ _ h, h)
id                └──────────────────┘    └──┘
src  ─┘  └───────┘└──────────────────┘└─┘        └─┘  └──────────────┘ └─
typ  ─┘  └───────┘└──────────────────┘└─┘ └──┘   └─┘  └──────────────┘ └─
doc  ─┘  └───────┘└──────────────────┘└─┘        └─┘  └──────────────┘ └─
txt  ─┘  └───────┘                    └─┘        └─┘  └──────────────┘ └─
par  ─┘  └───────┘                    └─┘        └─┘  └──────────────┘ └─
pid  ─┘  └───────┘                    └─┘        └─┘  └──────────────┘ └─
st   ──────────────────────────────────────────────────────────────────────
196    (λ x h₁ h₂, ⟨x, _, _, rfl⟩) _,
id                           └─┘
src  ─┘  └────────┘  └──────┘└─┘└──┘
typ  ─┘  └────────┘  └──────┘└─┘└──┘
doc  ─┘  └────────┘  └──────┘   └──┘
txt  ─┘  └────────┘  └──────┘   └──┘
par  ─┘  └────────┘  └──────┘   └──┘
pid  ─┘  └────────┘  └──────┘   └──┘
st   ──────────────────────────────┘└─
197    { rw [mem_product, mem_support_iff, mem_support_iff],
id           └─────────┘  └─────────────┘  └─────────────┘
src      └──┘└─────────┘└┘└─────────────┘└┘└─────────────┘
typ      └──┘└─────────┘└┘└─────────────┘└┘└─────────────┘
doc      └──┘           └┘               └┘               
txt      └──┘           └┘               └┘               
par      └──┘           └┘               └┘               
pid        └┘           └┘               └┘               
st   ───┘└─────────────┘└───────────────┘└───────────────┘└──
198      exact ⟨ne_zero_of_mul_ne_zero_right h₂, ne_zero_of_mul_ne_zero_left h₂⟩ },
id              └──────────────────────────┘     └─────────────────────────┘ └┘
src      └────┘ └──────────────────────────┘  └┘└─────────────────────────┘  └┘
typ      └────┘ └──────────────────────────┘  └┘└─────────────────────────┘└┘└┘
doc      └────┘                               └┘                             └┘
txt      └────┘                               └┘                             └┘
par      └────┘                               └┘                             └┘
pid                                          └┘                             
st   ───────────────────────────────────────────────────────────────────────────┘└┘
199    { rw nat.mem_antidiagonal at h₁, rwa [if_pos h₁] },
id          └──────────────────┘             └────┘ └┘
src      └─┘└──────────────────┘└────┘  └───┘└────┘  └┘
typ      └─┘└──────────────────┘└────┘  └───┘└────┘└┘└┘
doc      └─┘└──────────────────┘└────┘  └───┘        └┘
txt      └─┘                    └────┘  └───┘        └┘
par      └─┘                    └────┘  └───┘        └┘
pid                            └────┘     └┘        
st   ───┘└───────────────────────────┘└──────────────┘└┘
200    { intros x h hx, rw [if_pos (hite x hx)] }
id                          └────┘  └──┘  └┘
src      └───────────┘  └──┘└────┘        └─┘
typ      └───────────┘  └──┘└────┘ └──┘└┘└─┘
doc      └───────────┘  └──┘              └─┘
txt      └───────────┘  └──┘              └─┘
par      └───────────┘  └──┘              └─┘
pid            └─────┘    └┘              └┘
st   ────────────────┘└──────────────────────┘└─
201  end
st   ──┘
202  
203  theorem coeff_mul_X_pow (p : polynomial α) (n d : ℕ) :
id                                └────────┘          
src                               └────────┘           
typ                               └────────┘          
doc                               └────────┘
204    coeff (p * polynomial.X ^ n) (d + n) = coeff p d :=
id     └───┘    └──────────┘          └───┘  
src    └───┘     └──────────┘             └───┘
typ    └───┘    └──────────┘          └───┘  
doc    └───┘      └──────────┘                └───┘
205  begin
st   └─────
206    rw [coeff_mul, sum_eq_single (d,n), coeff_X_pow, if_pos rfl, mul_one],
id         └───────┘  └───────────┘     └─────────┘  └────┘ └─┘  └─────┘
src    └──┘└───────┘└┘└───────────┘  └─┘└─────────┘└┘└────┘└─┘└┘└─────┘
typ    └──┘└───────┘└┘└───────────┘└─┘└─────────┘└┘└────┘└─┘└┘└─────┘
doc    └──┘         └┘                └─┘           └┘         └┘       
txt    └──┘         └┘                └─┘           └┘         └┘       
par    └──┘         └┘                └─┘           └┘         └┘       
pid      └┘         └┘                └─┘           └┘         └┘       
st   ──────────────┘└───────────────────┘└───────────┘└──────────┘└───────┘└──
207    { rintros ⟨i,j⟩ h1 h2, rw [coeff_X_pow, if_neg, mul_zero], rintro rfl, apply h2,
id                                └─────────┘  └────┘  └──────┘
src      └─────────────────┘  └──┘└─────────┘└┘└────┘└┘└──────┘  └────────┘  └────┘
typ      └─────────────────┘  └──┘└─────────┘└┘└────┘└┘└──────┘  └────────┘  └────┘
doc      └─────────────────┘  └──┘           └┘      └┘          └────────┘  └────┘
txt      └─────────────────┘  └──┘           └┘      └┘          └────────┘  └────┘
par      └─────────────────┘  └──┘           └┘      └┘          └────────┘  └────┘
pid             └──────────┘    └┘           └┘      └┘                └──┘       
st   ───┘└─────────────────┘└───────────────┘└──────┘└────────┘└───────────┘└────────┘└─
208      rw [nat.mem_antidiagonal, add_right_cancel_iff] at h1, subst h1 },
id           └──────────────────┘  └──────────────────┘               └┘
src      └──┘└──────────────────┘└┘└──────────────────┘└─────┘  └────┘  
typ      └──┘└──────────────────┘└┘└──────────────────┘└─────┘  └────┘└┘
doc      └──┘└──────────────────┘└┘                    └─────┘  └────┘  
txt      └──┘                    └┘                    └─────┘  └────┘  
par      └──┘                    └┘                    └─────┘  └────┘  
pid        └┘                    └┘                    └────┘         
st   ───────────────────────────┘└────────────────────┘└────┘└─────────┘└┘
209    { exact λ h1, (h1 (nat.mem_antidiagonal.2 rfl)).elim }
id                        └──────────────────┘   └─┘
src      └────┘ └───┘    └──────────────────┘└─┘└─┘└──────┘
typ      └────┘ └───┘    └──────────────────┘└─┘└─┘└──────┘
doc      └────┘ └───┘    └──────────────────┘└─┘   └──────┘
txt      └────┘ └───┘                        └─┘   └──────┘
par      └────┘ └───┘                        └─┘   └──────┘
pid            └───┘                        └─┘   └────┘└┘
st   ──────────────────────────────────────────────────────┘└─
210  end
st   ──┘
211  
212  theorem coeff_mul_X (p : polynomial α) (n : ℕ) :
id                            └────────┘        
src                           └────────┘         
typ                           └────────┘        
doc                           └────────┘
213    coeff (p * X) (n + 1) = coeff p n :=
id     └───┘             └───┘  
src    └───┘               └───┘
typ    └───┘             └───┘  
doc    └───┘                  └───┘
214  by simpa only [pow_one] using coeff_mul_X_pow p 1 n
id                  └─────┘        └─────────────┘    
src     └──────────┘└─────┘└──────┘└─────────────┘ └─┘ 
typ     └──────────┘└─────┘└──────┘└─────────────┘└─┘
doc     └──────────┘       └──────┘                └─┘ 
txt     └──────────┘       └──────┘                └─┘ 
par     └──────────┘       └──────┘                └─┘ 
pid          └──┘└┘       └────┘                └─┘ 
st     └─────────────────────────────────────────────────
215  
src  
typ  
doc  
txt  
par  
pid  
st   
216  theorem mul_X_pow_eq_zero {p : polynomial α} {n : ℕ}
id                                  └────────┘        
src                                 └────────┘         
typ                                 └────────┘        
doc                                 └────────┘
217    (H : p * X ^ n = 0) : p = 0 :=
id                      
src                        
typ                     
doc             
218  ext $ λ k, (coeff_mul_X_pow p n k).symm.trans $ ext_iff.1 H (k+n)
id   └─┘        └─────────────┘    └──┘ └───┘    └─────┘    
src  └─┘         └─────────────┘       └──┘ └───┘    └─────┘      
typ  └─┘        └─────────────┘    └──┘ └───┘    └─────┘    
219  
220  end coeff
221  
222  lemma C_inj : C a = C b ↔ a = b :=
id                         
src                          
typ                        
doc                     
223  ⟨λ h, coeff_C_zero.symm.trans (h.symm ▸ coeff_C_zero), congr_arg C⟩
id        └──────────┘└───┘└────┘  └───┘  └──────────┘   └───────┘ 
src        └──────────┘└───┘└────┘   └───┘  └──────────┘   └───────┘ 
typ       └──────────┘└───┘└────┘  └───┘  └──────────┘   └───────┘ 
doc                                                                   
224  
225  section eval₂
226  variables [semiring β]
id              └──────┘
src             └──────┘
typ             └──────┘
227  variables (f : α → β) (x : β)
228  open is_semiring_hom
229  
230  /-- Evaluate a polynomial `p` given a ring hom `f` from the scalar ring
231    to the target and a value `x` for the variable in the target -/
232  def eval₂ (p : polynomial α) : β :=
id                  └────────┘     
src                 └────────┘
typ                 └────────┘     
doc                 └────────┘
233  p.sum (λ e a, f a * x ^ e)
id   └──┘            
src   └──┘                
typ  └──┘            
doc   └──┘
234  
235  variables [is_semiring_hom f]
id              └─────────────┘
src             └─────────────┘
typ             └─────────────┘
doc             └─────────────┘
236  
237  @[simp] lemma eval₂_C : (C a).eval₂ f x = f a :=
id                              └───┘      
src                              └───┘      
typ                             └───┘      
doc    └──┘                      └───┘
238  (sum_single_index $ by rw [map_zero f, zero_mul]).trans $ by rw [pow_zero, mul_one]
id    └──────────────┘          └──────┘   └──────┘  └───┘           └──────┘  └─────┘
src   └──────────────┘      └──┘└──────┘ └┘└──────┘ └───┘       └──┘└──────┘└┘└─────┘└─
typ   └──────────────┘      └──┘└──────┘└┘└──────┘ └───┘       └──┘└──────┘└┘└─────┘└─
doc                         └──┘         └┘                     └──┘        └┘       └─
txt                         └──┘         └┘                     └──┘        └┘       └─
par                         └──┘         └┘                     └──┘        └┘       └─
pid                           └┘         └┘                       └┘        └┘       
st                         └─────────────┘└────────┘            └───────────┘└───────┘
239  
src  
typ  
doc  
txt  
par  
pid  
st   
240  @[simp] lemma eval₂_X : X.eval₂ f x = x :=
id                           └────┘    
src                          └────┘     
typ                          └────┘    
doc    └──┘                  └────┘
241  (sum_single_index $ by rw [map_zero f, zero_mul]).trans $ by rw [map_one f, one_mul, pow_one]
id    └──────────────┘          └──────┘   └──────┘  └───┘           └─────┘   └─────┘  └─────┘
src   └──────────────┘      └──┘└──────┘ └┘└──────┘ └───┘       └──┘└─────┘ └┘└─────┘└┘└─────┘└─
typ   └──────────────┘      └──┘└──────┘└┘└──────┘ └───┘       └──┘└─────┘└┘└─────┘└┘└─────┘└─
doc                         └──┘         └┘                     └──┘        └┘       └┘       └─
txt                         └──┘         └┘                     └──┘        └┘       └┘       └─
par                         └──┘         └┘                     └──┘        └┘       └┘       └─
pid                           └┘         └┘                       └┘        └┘       └┘       
st                         └─────────────┘└────────┘            └────────────┘└───────┘└───────┘
242  
src  
typ  
doc  
txt  
par  
pid  
st   
243  @[simp] lemma eval₂_zero : (0 : polynomial α).eval₂ f x = 0 :=
id                                   └────────┘  └───┘    
src                                  └────────┘   └───┘      
typ                                  └────────┘  └───┘    
doc    └──┘                          └────────┘   └───┘
244  finsupp.sum_zero_index
id   └────────────────────┘
src  └────────────────────┘
typ  └────────────────────┘
245  
246  @[simp] lemma eval₂_add : (p + q).eval₂ f x = p.eval₂ f x + q.eval₂ f x :=
id                                 └───┘     └────┘    └────┘  
src                                  └───┘        └────┘       └────┘
typ                                └───┘     └────┘    └────┘  
doc    └──┘                           └───┘         └────┘        └────┘
247  finsupp.sum_add_index
id   └───────────────────┘
src  └───────────────────┘
typ  └───────────────────┘
248    (λ _, by rw [map_zero f, zero_mul])
id                 └──────┘   └──────┘
src             └──┘└──────┘ └┘└──────┘
typ            └──┘└──────┘└┘└──────┘
doc             └──┘         └┘        
txt             └──┘         └┘        
par             └──┘         └┘        
pid               └┘         └┘        
st             └─────────────┘└────────┘
249    (λ _ _ _, by rw [map_add f, add_mul])
id                   └─────┘   └─────┘
src                 └──┘└─────┘ └┘└─────┘
typ              └──┘└─────┘└┘└─────┘
doc                 └──┘        └┘       
txt                 └──┘        └┘       
par                 └──┘        └┘       
pid                   └┘        └┘       
st                 └────────────┘└───────┘
250  
251  @[simp] lemma eval₂_one : (1 : polynomial α).eval₂ f x = 1 :=
id                                  └────────┘  └───┘    
src                                 └────────┘   └───┘      
typ                                 └────────┘  └───┘    
doc    └──┘                         └────────┘   └───┘
252  by rw [← C_1, eval₂_C, map_one f]
id            └─┘  └─────┘  └─────┘ 
src     └────┘└─┘└┘└─────┘└┘└─────┘ └─
typ     └────┘└─┘└┘└─────┘└┘└─────┘└─
doc     └────┘   └┘       └┘        └─
txt     └────┘   └┘       └┘        └─
par     └────┘   └┘       └┘        └─
pid       └──┘   └┘       └┘        
st     └────────┘└───────┘└─────────┘
253  
src  
typ  
doc  
txt  
par  
pid  
st   
254  instance eval₂.is_add_monoid_hom : is_add_monoid_hom (eval₂ f x) :=
id                                      └───────────────┘  └───┘  
src                                     └───────────────┘  └───┘
typ                                     └───────────────┘  └───┘  
doc                                     └───────────────┘  └───┘
255  { map_zero := eval₂_zero _ _, map_add := λ _ _, eval₂_add _ _ }
id                 └────────┘                      └───────┘
src                └────────┘                        └───────┘
typ                └────────┘                      └───────┘
256  
257  end eval₂
258  
259  section eval₂
260  variables [comm_semiring β]
id              └───────────┘
src             └───────────┘
typ             └───────────┘
261  variables (f : α → β) [is_semiring_hom f] (x : β)
id                          └─────────────┘
src                         └─────────────┘
typ                         └─────────────┘
doc                         └─────────────┘
262  open is_semiring_hom
263  
264  @[simp] lemma eval₂_mul : (p * q).eval₂ f x = p.eval₂ f x * q.eval₂ f x :=
id                                 └───┘     └────┘    └────┘  
src                                  └───┘        └────┘       └────┘
typ                                └───┘     └────┘    └────┘  
doc    └──┘                           └───┘         └────┘        └────┘
265  begin
st   └─────
266    dunfold eval₂,
src    └───────────┘
typ    └───────────┘
doc    └───────────┘
txt    └───────────┘
par    └───────────┘
pid           └────┘
st   ──────────────┘└─
267    rw [mul_def, finsupp.sum_mul _ p], simp only [finsupp.mul_sum _ q], rw [sum_sum_index],
id         └─────┘  └─────────────┘                 └─────────────┘          └───────────┘
src    └──┘└─────┘└┘└─────────────┘└─┘   └─────────┘└─────────────┘└─┘   └──┘└───────────┘
typ    └──┘└─────┘└┘└─────────────┘└─┘  └─────────┘└─────────────┘└─┘  └──┘└───────────┘
doc    └──┘       └┘               └─┘   └─────────┘               └─┘   └──┘             
txt    └──┘       └┘               └─┘   └─────────┘               └─┘   └──┘             
par    └──┘       └┘               └─┘   └─────────┘               └─┘   └──┘             
pid      └┘       └┘               └─┘       └──┘└┘               └─┘     └┘             
st   ────────────┘└───────────────────┘└────────────────────────────────┘└─────────────────┘└──
268    { apply sum_congr rfl, assume i hi, dsimp only, rw [sum_sum_index],
id             └───────┘ └─┘                               └───────────┘
src      └────┘└───────┘└─┘  └─────────┘  └────────┘  └──┘└───────────┘
typ      └────┘└───────┘└─┘  └─────────┘  └────────┘  └──┘└───────────┘
doc      └────┘              └─────────┘  └────────┘  └──┘             
txt      └────┘              └─────────┘  └────────┘  └──┘             
par      └────┘              └─────────┘  └────────┘  └──┘             
pid                         └─────────┘       └───┘    └┘             
st   ───┘└─────────────────┘└───────────┘└──────────┘└─────────────────┘└──
269      { apply sum_congr rfl, assume j hj, dsimp only,
id               └───────┘ └─┘
src        └────┘└───────┘└─┘  └─────────┘  └────────┘
typ        └────┘└───────┘└─┘  └─────────┘  └────────┘
doc        └────┘              └─────────┘  └────────┘
txt        └────┘              └─────────┘  └────────┘
par        └────┘              └─────────┘  └────────┘
pid                           └─────────┘       └───┘
st   ─────┘└─────────────────┘└───────────┘└──────────┘└─
270        rw [sum_single_index, map_mul f, pow_add],
id             └──────────────┘  └─────┘   └─────┘
src        └──┘└──────────────┘└┘└─────┘ └┘└─────┘
typ        └──┘└──────────────┘└┘└─────┘└┘└─────┘
doc        └──┘                └┘        └┘       
txt        └──┘                └┘        └┘       
par        └──┘                └┘        └┘       
pid          └┘                └┘        └┘       
st   ─────────────────────────┘└─────────┘└───────┘└──
271        { simp only [mul_assoc, mul_left_comm] },
id                      └───────┘  └───────────┘
src          └─────────┘└───────┘└┘└───────────┘└┘
typ          └─────────┘└───────┘└┘└───────────┘└┘
doc          └─────────┘         └┘             └┘
txt          └─────────┘         └┘             └┘
par          └─────────┘         └┘             └┘
pid              └──┘└┘         └┘             
st   ───────┘└───────────────────────────────────┘└┘
272        { rw [map_zero f, zero_mul] } },
id               └──────┘   └──────┘
src          └──┘└──────┘ └┘└──────┘└┘
typ          └──┘└──────┘└┘└──────┘└┘
doc          └──┘         └┘        └┘
txt          └──┘         └┘        └┘
par          └──┘         └┘        └┘
pid            └┘         └┘        
st   ─────────────────────┘└────────┘└──┘
273      { intro, rw [map_zero f, zero_mul] },
id                    └──────┘   └──────┘
src        └───┘  └──┘└──────┘ └┘└──────┘└┘
typ        └───┘  └──┘└──────┘└┘└──────┘└┘
doc        └───┘  └──┘         └┘        └┘
txt        └───┘  └──┘         └┘        └┘
par        └───┘  └──┘         └┘        └┘
pid                 └┘         └┘        
st   ─────┘└───┘└──────────────┘└────────┘└┘
274      { intros, rw [map_add f, add_mul] } },
id                     └─────┘   └─────┘
src        └────┘  └──┘└─────┘ └┘└─────┘└┘
typ        └────┘  └──┘└─────┘└┘└─────┘└┘
doc        └────┘  └──┘        └┘       └┘
txt        └────┘  └──┘        └┘       └┘
par        └────┘  └──┘        └┘       └┘
pid                  └┘        └┘       
st   ───────────┘└─────────────┘└───────┘└──┘
275    { intro, rw [map_zero f, zero_mul] },
id                  └──────┘   └──────┘
src      └───┘  └──┘└──────┘ └┘└──────┘└┘
typ      └───┘  └──┘└──────┘└┘└──────┘└┘
doc      └───┘  └──┘         └┘        └┘
txt      └───┘  └──┘         └┘        └┘
par      └───┘  └──┘         └┘        └┘
pid               └┘         └┘        
st   ───┘└───┘└──────────────┘└────────┘└┘
276    { intros, rw [map_add f, add_mul] }
id                   └─────┘   └─────┘
src      └────┘  └──┘└─────┘ └┘└─────┘└┘
typ      └────┘  └──┘└─────┘└┘└─────┘└┘
doc      └────┘  └──┘        └┘       └┘
txt      └────┘  └──┘        └┘       └┘
par      └────┘  └──┘        └┘       └┘
pid                └┘        └┘       
st   ─────────┘└─────────────┘└───────┘└─
277  end
st   ──┘
278  
279  instance eval₂.is_semiring_hom : is_semiring_hom (eval₂ f x) :=
id                                    └─────────────┘  └───┘  
src                                   └─────────────┘  └───┘
typ                                   └─────────────┘  └───┘  
doc                                   └─────────────┘  └───┘
280  ⟨eval₂_zero _ _, eval₂_one _ _, λ _ _, eval₂_add _ _, λ _ _, eval₂_mul _ _⟩
id    └────────┘      └───────┘           └───────┘           └───────┘
src   └────────┘      └───────┘             └───────┘             └───────┘
typ   └────────┘      └───────┘           └───────┘           └───────┘
281  
282  lemma eval₂_pow (n : ℕ) : (p ^ n).eval₂ f x = p.eval₂ f x ^ n := map_pow _ _ _
id                                └───┘     └────┘        └─────┘
src                                 └───┘        └────┘           └─────┘
typ                               └───┘     └────┘        └─────┘
doc                                   └───┘         └────┘
283  
284  lemma eval₂_sum (p : polynomial α) (g : ℕ → α → polynomial α) (x : β) :
id                        └────────┘              └────────┘        
src                       └────────┘                └────────┘
typ                       └────────┘              └────────┘        
doc                       └────────┘                 └────────┘
285    (p.sum g).eval₂ f x = p.sum (λ n a, (g n a).eval₂ f x) :=
id      └──┘  └───┘     └──┘           └───┘   
src      └──┘   └───┘        └──┘                └───┘
typ     └──┘  └───┘     └──┘           └───┘   
doc      └──┘   └───┘         └──┘                └───┘
286  finsupp.sum_sum_index (by simp [is_add_monoid_hom.map_zero f])
id   └───────────────────┘           └────────────────────────┘ 
src  └───────────────────┘     └────┘└────────────────────────┘ 
typ  └───────────────────┘     └────┘└────────────────────────┘
doc                            └────┘                           
txt                            └────┘                           
par                            └────┘                           
pid                                                           
st                            └──────────────────────────────────┘
287    (by intros; simp [right_distrib, is_add_monoid_hom.map_add f])
id                       └───────────┘  └───────────────────────┘ 
src        └────┘  └────┘└───────────┘└┘└───────────────────────┘ 
typ        └────┘  └────┘└───────────┘└┘└───────────────────────┘
doc        └────┘  └────┘             └┘                          
txt        └────┘  └────┘             └┘                          
par        └────┘  └────┘             └┘                          
pid                                 └┘                          
st        └────────────────────────────────────────────────────────┘
288  
289  end eval₂
290  
291  section eval
292  variable {x : α}
293  
294  /-- `eval x p` is the evaluation of the polynomial `p` at `x` -/
295  def eval : α → polynomial α → α := eval₂ id
id                 └────────┘        └───┘ └┘
src                 └────────┘          └───┘ └┘
typ                └────────┘        └───┘ └┘
doc                 └────────┘          └───┘
296  
297  @[simp] lemma eval_C : (C a).eval x = a := eval₂_C _ _
id                             └──┘        └─────┘
src                             └──┘          └─────┘
typ                            └──┘        └─────┘
doc    └──┘                     └──┘
298  
299  @[simp] lemma eval_X : X.eval x = x := eval₂_X _ _
id                          └───┘       └─────┘
src                         └───┘         └─────┘
typ                         └───┘       └─────┘
doc    └──┘                 └───┘
300  
301  @[simp] lemma eval_zero : (0 : polynomial α).eval x = 0 :=  eval₂_zero _ _
id                                  └────────┘  └──┘          └────────┘
src                                 └────────┘   └──┘           └────────┘
typ                                 └────────┘  └──┘          └────────┘
doc    └──┘                         └────────┘   └──┘
302  
303  @[simp] lemma eval_add : (p + q).eval x = p.eval x + q.eval x := eval₂_add _ _
id                                └──┘    └───┘   └───┘     └───────┘
src                                 └──┘      └───┘     └───┘      └───────┘
typ                               └──┘    └───┘   └───┘     └───────┘
doc    └──┘                          └──┘       └───┘      └───┘
304  
305  @[simp] lemma eval_one : (1 : polynomial α).eval x = 1 := eval₂_one _ _
id                                 └────────┘  └──┘         └───────┘
src                                └────────┘   └──┘          └───────┘
typ                                └────────┘  └──┘         └───────┘
doc    └──┘                        └────────┘   └──┘
306  
307  @[simp] lemma eval_mul : (p * q).eval x = p.eval x * q.eval x := eval₂_mul _ _
id                                └──┘    └───┘   └───┘     └───────┘
src                                 └──┘      └───┘     └───┘      └───────┘
typ                               └──┘    └───┘   └───┘     └───────┘
doc    └──┘                          └──┘       └───┘      └───┘
308  
309  instance eval.is_semiring_hom : is_semiring_hom (eval x) := eval₂.is_semiring_hom _ _
id                                   └─────────────┘  └──┘      └───────────────────┘
src                                  └─────────────┘  └──┘       └───────────────────┘
typ                                  └─────────────┘  └──┘      └───────────────────┘
doc                                  └─────────────┘  └──┘
310  
311  @[simp] lemma eval_pow (n : ℕ) : (p ^ n).eval x = p.eval x ^ n := eval₂_pow _ _ _
id                                       └──┘    └───┘       └───────┘
src                                        └──┘      └───┘         └───────┘
typ                                      └──┘    └───┘       └───────┘
doc    └──┘                                  └──┘       └───┘
312  
313  lemma eval_sum (p : polynomial α) (f : ℕ → α → polynomial α) (x : α) :
id                       └────────┘              └────────┘        
src                      └────────┘                └────────┘
typ                      └────────┘              └────────┘        
doc                      └────────┘                 └────────┘
314    (p.sum f).eval x = p.sum (λ n a, (f n a).eval x) :=
id      └──┘  └──┘    └──┘           └──┘  
src      └──┘   └──┘      └──┘                └──┘
typ     └──┘  └──┘    └──┘           └──┘  
doc      └──┘   └──┘       └──┘                └──┘
315  eval₂_sum _ _ _ _
id   └───────┘
src  └───────┘
typ  └───────┘
316  
317  lemma eval₂_hom [comm_semiring β] (f : α → β) [is_semiring_hom f] (x : α) :
id                    └───────────┘              └─────────────┘        
src                   └───────────┘                 └─────────────┘
typ                   └───────────┘              └─────────────┘        
doc                                                 └─────────────┘
318    p.eval₂ f (f x) = f (p.eval x) :=
id     └────┘         └───┘ 
src     └────┘              └───┘
typ    └────┘         └───┘ 
doc     └────┘               └───┘
319  polynomial.induction_on p
id   └─────────────────────┘ 
src  └─────────────────────┘
typ  └─────────────────────┘ 
320    (by simp)
src        └──┘
typ        └──┘
doc        └──┘
txt        └──┘
par        └──┘
st        └───┘
321    (by simp [is_semiring_hom.map_add f] {contextual := tt})
id               └─────────────────────┘                  └┘
src        └────┘└─────────────────────┘ └┘ └────────────┘└┘
typ        └────┘└─────────────────────┘└┘ └────────────┘└┘
doc        └────┘                        └┘ └────────────┘  
txt        └────┘                        └┘ └────────────┘  
par        └────┘                        └┘ └────────────┘  
pid                                     └────────────┘  
st        └──────────────────────────────────────────────────┘
322    (by simp [is_semiring_hom.map_mul f, eval_pow,
id               └─────────────────────┘   └──────┘
src        └────┘└─────────────────────┘ └┘└──────┘└─
typ        └────┘└─────────────────────┘└┘└──────┘└─
doc        └────┘                        └┘        └─
txt        └────┘                        └┘        └─
par        └────┘                        └┘        └─
pid                                    └┘        └─
st        └───────────────────────────────────────────
323      is_semiring_hom.map_pow f, pow_succ', (mul_assoc _ _ _).symm] {contextual := tt})
id       └─────────────────────┘   └───────┘   └───────┘                             └┘
src  ───┘└─────────────────────┘ └┘└───────┘└┘ └───────┘└────────────┘ └────────────┘└┘
typ  ───┘└─────────────────────┘└┘└───────┘└┘ └───────┘└────────────┘ └────────────┘└┘
doc  ───┘                        └┘         └┘          └────────────┘ └────────────┘  
txt  ───┘                        └┘         └┘          └────────────┘ └────────────┘  
par  ───┘                        └┘         └┘          └────────────┘ └────────────┘  
pid  ───┘                        └┘         └┘          └───────────┘ └────────────┘  
st   ───────────────────────────────────────────────────────────────────────────────────┘
324  
325  /-- `is_root p x` implies `x` is a root of `p`. The evaluation of `p` at `x` is zero -/
326  def is_root (p : polynomial α) (a : α) : Prop := p.eval a = 0
id                    └────────┘                    └───┘  
src                   └────────┘                       └───┘   
typ                   └────────┘                    └───┘  
doc                   └────────┘                       └───┘
327  
328  instance [decidable_eq α] : decidable (is_root p a) := by unfold is_root; apply_instance
id             └──────────┘     └───────┘  └─────┘  
src            └──────────┘      └───────┘  └─────┘            └────────────┘  └──────────────
typ            └──────────┘     └───────┘  └─────┘          └────────────┘  └──────────────
doc                                         └─────┘            └────────────┘  └──────────────
txt                                                            └────────────┘  └──────────────
par                                                            └────────────┘  └──────────────
pid                                                                  └──────┘                
st                                                            └───────────────────────────────
329  
src  
typ  
doc  
txt  
par  
pid  
st   
330  @[simp] lemma is_root.def : is_root p a ↔ p.eval a = 0 := iff.rfl
id                               └─────┘    └───┘        └─────┘
src                              └─────┘       └───┘         └─────┘
typ                              └─────┘    └───┘        └─────┘
doc    └──┘                      └─────┘        └───┘
331  
332  lemma root_mul_left_of_is_root (p : polynomial α) {q : polynomial α} :
id                                       └────────┘        └────────┘ 
src                                      └────────┘         └────────┘
typ                                      └────────┘        └────────┘ 
doc                                      └────────┘         └────────┘
333    is_root q a → is_root (p * q) a :=
id     └─────┘     └─────┘      
src    └─────┘       └─────┘    
typ    └─────┘     └─────┘      
doc    └─────┘       └─────┘
334  λ H, by rw [is_root, eval_mul, is_root.def.1 H, mul_zero]
id              └─────┘  └──────┘  └─────────┘     └──────┘
src          └──┘└─────┘└┘└──────┘└┘└─────────┘└─┘ └┘└──────┘└─
typ         └──┘└─────┘└┘└──────┘└┘└─────────┘└─┘└┘└──────┘└─
doc          └──┘└─────┘└┘        └┘           └─┘ └┘        └─
txt          └──┘       └┘        └┘           └─┘ └┘        └─
par          └──┘       └┘        └┘           └─┘ └┘        └─
pid            └┘       └┘        └┘           └─┘ └┘        
st          └──────────┘└────────┘└───────────────┘└────────┘
335  
src  
typ  
doc  
txt  
par  
pid  
st   
336  lemma root_mul_right_of_is_root {p : polynomial α} (q : polynomial α) :
id                                        └────────┘        └────────┘ 
src                                       └────────┘         └────────┘
typ                                       └────────┘        └────────┘ 
doc                                       └────────┘         └────────┘
337    is_root p a → is_root (p * q) a :=
id     └─────┘     └─────┘      
src    └─────┘       └─────┘    
typ    └─────┘     └─────┘      
doc    └─────┘       └─────┘
338  λ H, by rw [is_root, eval_mul, is_root.def.1 H, zero_mul]
id              └─────┘  └──────┘  └─────────┘     └──────┘
src          └──┘└─────┘└┘└──────┘└┘└─────────┘└─┘ └┘└──────┘└─
typ         └──┘└─────┘└┘└──────┘└┘└─────────┘└─┘└┘└──────┘└─
doc          └──┘└─────┘└┘        └┘           └─┘ └┘        └─
txt          └──┘       └┘        └┘           └─┘ └┘        └─
par          └──┘       └┘        └┘           └─┘ └┘        └─
pid            └┘       └┘        └┘           └─┘ └┘        
st          └──────────┘└────────┘└───────────────┘└────────┘
339  
src  
typ  
doc  
txt  
par  
pid  
st   
340  lemma coeff_zero_eq_eval_zero (p : polynomial α) :
id                                      └────────┘ 
src                                     └────────┘
typ                                     └────────┘ 
doc                                     └────────┘
341    coeff p 0 = p.eval 0 :=
id     └───┘     └───┘
src    └───┘       └───┘
typ    └───┘     └───┘
doc    └───┘        └───┘
342  calc coeff p 0 = coeff p 0 * 0 ^ 0 : by simp
id        └───┘      └───┘       
src       └───┘       └───┘                └───┘
typ       └───┘      └───┘               └───┘
doc       └───┘       └───┘                  └───┘
txt                                          └───┘
par                                          └───┘
pid                                              
st                                          └────┘
343  ... = p.eval 0 : eq.symm $
id         └───┘     └─────┘
src         └───┘     └─────┘
typ        └───┘     └─────┘
doc         └───┘
344    finset.sum_eq_single _ (λ b _ hb, by simp [zero_pow (nat.pos_of_ne_zero hb)]) (by simp)
id     └──────────────────┘        └┘           └──────┘  └────────────────┘ └┘
src    └──────────────────┘                 └────┘└──────┘ └────────────────┘  └┘      └──┘
typ    └──────────────────┘        └┘     └────┘└──────┘ └────────────────┘└┘└┘      └──┘
doc                                         └────┘                             └┘      └──┘
txt                                         └────┘                             └┘      └──┘
par                                         └────┘                             └┘      └──┘
pid                                                                          └┘
st                                         └──────────────────────────────────────┘     └───┘
345  
346  lemma zero_is_root_of_coeff_zero_eq_zero {p : polynomial α} (hp : p.coeff 0 = 0) :
id                                                 └────────┘         └────┘   
src                                                └────────┘           └────┘   
typ                                                └────────┘         └────┘   
doc                                                └────────┘           └────┘
347    is_root p 0 :=
id     └─────┘ 
src    └─────┘
typ    └─────┘ 
doc    └─────┘
348  by rwa coeff_zero_eq_eval_zero at hp
id          └─────────────────────┘
src     └──┘└─────────────────────┘└──────
typ     └──┘└─────────────────────┘└──────
doc     └──┘                       └──────
txt     └──┘                       └──────
par     └──┘                       └──────
pid                               └────┘
st     └──────────────────────────────────
349  
src  
typ  
doc  
txt  
par  
pid  
st   
350  end eval
351  
352  section comp
353  
354  def comp (p q : polynomial α) : polynomial α := p.eval₂ C q
id                   └────────┘     └────────┘     └────┘  
src                  └────────┘      └────────┘       └────┘ 
typ                  └────────┘     └────────┘     └────┘  
doc                  └────────┘      └────────┘       └────┘ 
355  
356  lemma eval₂_comp [comm_semiring β] (f : α → β) [is_semiring_hom f] {x : β} :
id                     └───────────┘              └─────────────┘        
src                    └───────────┘                 └─────────────┘
typ                    └───────────┘              └─────────────┘        
doc                                                  └─────────────┘
357    (p.comp q).eval₂ f x = p.eval₂ f (q.eval₂ f x) :=
id      └───┘  └───┘     └────┘   └────┘  
src      └───┘   └───┘        └────┘     └────┘
typ     └───┘  └───┘     └────┘   └────┘  
doc              └───┘         └────┘     └────┘
358  show (p.sum (λ e a, C a * q ^ e)).eval₂ f x = p.eval₂ f (eval₂ f x q),
id         └──┘              └───┘     └────┘   └───┘   
src         └──┘                   └───┘        └────┘    └───┘
typ        └──┘              └───┘     └────┘   └───┘   
doc         └──┘                     └───┘         └────┘    └───┘
359  by simp only [eval₂_mul, eval₂_C, eval₂_pow, eval₂_sum]; refl
id                 └───────┘  └─────┘  └───────┘  └───────┘
src     └─────────┘└───────┘└┘└─────┘└┘└───────┘└┘└───────┘  └────
typ     └─────────┘└───────┘└┘└─────┘└┘└───────┘└┘└───────┘  └────
doc     └─────────┘         └┘       └┘         └┘           └────
txt     └─────────┘         └┘       └┘         └┘           └────
par     └─────────┘         └┘       └┘         └┘           └────
pid         └──┘└┘         └┘       └┘         └┘               
st     └───────────────────────────────────────────────────────────
360  
src  
typ  
doc  
txt  
par  
pid  
st   
361  lemma eval_comp : (p.comp q).eval a = p.eval (q.eval a) := eval₂_comp _
id                      └───┘  └──┘    └───┘  └───┘      └────────┘
src                      └───┘   └──┘      └───┘   └───┘       └────────┘
typ                     └───┘  └──┘    └───┘  └───┘      └────────┘
doc                              └──┘       └───┘   └───┘
362  
363  @[simp] lemma comp_X : p.comp X = p :=
id                          └───┘   
src                          └───┘  
typ                         └───┘   
doc    └──┘                        
364  begin
st   └─────
365    refine ext (λ n, _),
id            └─┘
src    └─────┘└─┘  └────┘
typ    └─────┘└─┘  └────┘
doc    └─────┘     └────┘
txt    └─────┘     └────┘
par    └─────┘     └────┘
pid               └────┘
st   ────────────────────┘└─
366    rw [comp, eval₂],
id         └──┘  └───┘
src    └──┘└──┘└┘└───┘
typ    └──┘└──┘└┘└───┘
doc    └──┘    └┘└───┘
txt    └──┘    └┘     
par    └──┘    └┘     
pid      └┘    └┘     
st   ─────────┘└─────┘└──
367    conv in (C _ * _) { rw ← single_eq_C_mul_X },
id                            └───────────────┘
src    └──────┘ └─┘└────┘└───┘└───────────────┘
typ    └──────┘ └─┘└────┘└───┘└───────────────┘
doc             
txt    └──────┘  └─┘ └────┘└───┘                 
par    └──────┘  └─┘ └────┘└───┘                 
pid        └─┘  └─┘ └─┘└──────┘                 └┘
st   ────────────────────┘└──────────────────────┘└┘
368    rw finsupp.sum_single
id        └────────────────┘
src    └─┘└────────────────┘
typ    └─┘└────────────────┘
doc    └─┘                  
txt    └─┘                  
par    └─┘                  
pid                        
st   ───────────────────────┘
369  end
st   └─┘
370  
371  @[simp] lemma X_comp : X.comp p = p := eval₂_X _ _
id                          └───┘       └─────┘
src                         └───┘         └─────┘
typ                         └───┘       └─────┘
doc    └──┘                 
372  
373  @[simp] lemma comp_C : p.comp (C a) = C (p.eval a) :=
id                          └───┘        └───┘ 
src                          └───┘          └───┘
typ                         └───┘        └───┘ 
doc    └──┘                                  └───┘
374  begin
st   └─────
375    dsimp [comp, eval₂, eval, finsupp.sum],
id            └──┘  └───┘  └──┘  └─────────┘
src    └─────┘└──┘└┘└───┘└┘└──┘└┘└─────────┘
typ    └─────┘└──┘└┘└───┘└┘└──┘└┘└─────────┘
doc    └─────┘    └┘└───┘└┘└──┘└┘└─────────┘
txt    └─────┘    └┘     └┘    └┘           
par    └─────┘    └┘     └┘    └┘           
pid             └┘     └┘    └┘           
st   ───────────────────────────────────────┘└─
376    rw [← p.support.sum_hom (@C α _)],
id           └───────────────┘    
src    └────┘└───────────────┘   └──┘
typ    └────┘└───────────────┘  └──┘
doc    └────┘                    └──┘
txt    └────┘                     └──┘
par    └────┘                     └──┘
pid      └──┘                     └──┘
st   ─────────────────────────────────┘└──
377    apply finset.sum_congr rfl; simp
id           └──────────────┘ └─┘
src    └────┘└──────────────┘└─┘  └───┘
typ    └────┘└──────────────┘└─┘  └───┘
doc    └────┘                     └───┘
txt    └────┘                     └───┘
par    └────┘                     └───┘
pid                                  
st   ──────────────────────────────────┘
378  end
st   └─┘
379  
380  @[simp] lemma C_comp : (C a).comp p = C a := eval₂_C _ _
id                             └──┘         └─────┘
src                             └──┘           └─────┘
typ                            └──┘         └─────┘
doc    └──┘                               
381  
382  @[simp] lemma comp_zero : p.comp (0 : polynomial α) = C (p.eval 0) :=
id                             └───┘      └────────┘      └───┘
src                             └───┘      └────────┘        └───┘
typ                            └───┘      └────────┘      └───┘
doc    └──┘                                └────────┘         └───┘
383  by rw [← C_0, comp_C]
id            └─┘  └────┘
src     └────┘└─┘└┘└────┘└─
typ     └────┘└─┘└┘└────┘└─
doc     └────┘   └┘      └─
txt     └────┘   └┘      └─
par     └────┘   └┘      └─
pid       └──┘   └┘      
st     └────────┘└──────┘
384  
src  
typ  
doc  
txt  
par  
pid  
st   
385  @[simp] lemma zero_comp : comp (0 : polynomial α) p = 0 :=
id                             └──┘      └────────┘    
src                            └──┘      └────────┘      
typ                            └──┘      └────────┘    
doc    └──┘                              └────────┘
386  by rw [← C_0, C_comp]
id            └─┘  └────┘
src     └────┘└─┘└┘└────┘└─
typ     └────┘└─┘└┘└────┘└─
doc     └────┘   └┘      └─
txt     └────┘   └┘      └─
par     └────┘   └┘      └─
pid       └──┘   └┘      
st     └────────┘└──────┘
387  
src  
typ  
doc  
txt  
par  
pid  
st   
388  @[simp] lemma comp_one : p.comp 1 = C (p.eval 1) :=
id                            └───┘      └───┘
src                            └───┘       └───┘
typ                           └───┘      └───┘
doc    └──┘                                 └───┘
389  by rw [← C_1, comp_C]
id            └─┘  └────┘
src     └────┘└─┘└┘└────┘└─
typ     └────┘└─┘└┘└────┘└─
doc     └────┘   └┘      └─
txt     └────┘   └┘      └─
par     └────┘   └┘      └─
pid       └──┘   └┘      
st     └────────┘└──────┘
390  
src  
typ  
doc  
txt  
par  
pid  
st   
391  @[simp] lemma one_comp : comp (1 : polynomial α) p = 1 :=
id                            └──┘      └────────┘    
src                           └──┘      └────────┘      
typ                           └──┘      └────────┘    
doc    └──┘                             └────────┘
392  by rw [← C_1, C_comp]
id            └─┘  └────┘
src     └────┘└─┘└┘└────┘└─
typ     └────┘└─┘└┘└────┘└─
doc     └────┘   └┘      └─
txt     └────┘   └┘      └─
par     └────┘   └┘      └─
pid       └──┘   └┘      
st     └────────┘└──────┘
393  
src  
typ  
doc  
txt  
par  
pid  
st   
394  instance : is_semiring_hom (λ q : polynomial α, q.comp p) :=
id              └─────────────┘        └────────┘   └───┘ 
src             └─────────────┘        └────────┘     └───┘
typ             └─────────────┘        └────────┘   └───┘ 
doc             └─────────────┘        └────────┘
395  by unfold comp; apply_instance
src     └─────────┘  └──────────────
typ     └─────────┘  └──────────────
doc     └─────────┘  └──────────────
txt     └─────────┘  └──────────────
par     └─────────┘  └──────────────
pid           └───┘                
st     └────────────────────────────
396  
src  
typ  
doc  
txt  
par  
pid  
st   
397  @[simp] lemma add_comp : (p + q).comp r = p.comp r + q.comp r := eval₂_add _ _
id                                └──┘    └───┘   └───┘     └───────┘
src                                 └──┘      └───┘     └───┘      └───────┘
typ                               └──┘    └───┘   └───┘     └───────┘
doc    └──┘
398  @[simp] lemma mul_comp : (p * q).comp r = p.comp r * q.comp r := eval₂_mul _ _
id                                └──┘    └───┘   └───┘     └───────┘
src                                 └──┘      └───┘     └───┘      └───────┘
typ                               └──┘    └───┘   └───┘     └───────┘
doc    └──┘
399  
400  end comp
401  
402  /-- `leading_coeff p` gives the coefficient of the highest power of `X` in `p`-/
403  def leading_coeff (p : polynomial α) : α := coeff p (nat_degree p)
id                          └────────┘         └───┘   └────────┘ 
src                         └────────┘           └───┘    └────────┘
typ                         └────────┘         └───┘   └────────┘ 
doc                         └────────┘           └───┘    └────────┘
404  
405  /-- a polynomial is `monic` if its leading coefficient is 1 -/
406  def monic (p : polynomial α) := leading_coeff p = (1 : α)
id                  └────────┘      └───────────┘        
src                 └────────┘       └───────────┘   
typ                 └────────┘      └───────────┘        
doc                 └────────┘       └───────────┘
407  
408  lemma monic.def : monic p ↔ leading_coeff p = 1 := iff.rfl
id                     └───┘   └───────────┘        └─────┘
src                    └───┘    └───────────┘         └─────┘
typ                    └───┘   └───────────┘        └─────┘
doc                    └───┘     └───────────┘
409  
410  instance monic.decidable [decidable_eq α] : decidable (monic p) :=
id                             └──────────┘     └───────┘  └───┘ 
src                            └──────────┘      └───────┘  └───┘
typ                            └──────────┘     └───────┘  └───┘ 
doc                                                         └───┘
411  by unfold monic; apply_instance
src     └──────────┘  └──────────────
typ     └──────────┘  └──────────────
doc     └──────────┘  └──────────────
txt     └──────────┘  └──────────────
par     └──────────┘  └──────────────
pid           └────┘                
st     └─────────────────────────────
412  
src  
typ  
doc  
txt  
par  
pid  
st   
413  @[simp] lemma monic.leading_coeff {p : polynomial α} (hp : p.monic) :
id                                          └────────┘         └────┘
src                                         └────────┘           └────┘
typ                                         └────────┘         └────┘
doc    └──┘                                 └────────┘           └────┘
414    leading_coeff p = 1 := hp
id     └───────────┘        └┘
src    └───────────┘   
typ    └───────────┘        └┘
doc    └───────────┘
415  
416  @[simp] lemma degree_zero : degree (0 : polynomial α) = ⊥ := rfl
id                               └────┘      └────────┘        └─┘
src                              └────┘      └────────┘         └─┘
typ                              └────┘      └────────┘        └─┘
doc    └──┘                      └────┘      └────────┘
417  
418  @[simp] lemma nat_degree_zero : nat_degree (0 : polynomial α) = 0 := rfl
id                                   └────────┘      └────────┘         └─┘
src                                  └────────┘      └────────┘          └─┘
typ                                  └────────┘      └────────┘         └─┘
doc    └──┘                          └────────┘      └────────┘
419  
420  @[simp] lemma degree_C (ha : a ≠ 0) : degree (C a) = (0 : with_bot ℕ) :=
id                                       └────┘           └──────┘ 
src                                       └────┘            └──────┘ 
typ                                      └────┘           └──────┘ 
doc    └──┘                                └────┘  
421  show sup (ite (a = 0) ∅ {0}) some = 0, by rw if_neg ha; refl
id        └─┘  └─┘            └──┘           └────┘ └┘
src       └─┘  └─┘             └──┘        └─┘└────┘    └────
typ       └─┘  └─┘            └──┘        └─┘└────┘└┘  └────
doc       └─┘                                  └─┘          └────
txt                                            └─┘          └────
par                                            └─┘          └────
pid                                                            
st                                            └───────────────────
422  
src  
typ  
doc  
txt  
par  
pid  
st   
423  lemma degree_C_le : degree (C a) ≤ (0 : with_bot ℕ) :=
id                       └────┘           └──────┘ 
src                      └────┘            └──────┘ 
typ                      └────┘           └──────┘ 
doc                      └────┘  
424  by by_cases h : a = 0; [rw [h, C_0], rw [degree_C h]]; [exact bot_le, exact le_refl _]
id                              └─┘       └──────┘           └────┘        └─────┘
src     └───────┘ └─┘ └┘  └──┘ └┘└─┘  └──┘└──────┘    └────┘└────┘  └────┘└─────┘└┘
typ     └───────┘ └─┘└┘  └──┘└┘└─┘  └──┘└──────┘   └────┘└────┘  └────┘└─────┘└┘
doc     └───────┘ └─┘  └┘   └──┘ └┘     └──┘             └────┘        └────┘       └┘
txt     └───────┘ └─┘  └┘   └──┘ └┘     └──┘             └────┘        └────┘       └┘
par     └───────┘ └─┘  └┘   └──┘ └┘     └──┘             └────┘        └────┘       └┘
pid              └─┘       └┘ └┘       └┘                                      └┘
st     └────────────────────────┘└───┘└────┘└────────┘└────────────────────────────────┘
425  
426  lemma degree_one_le : degree (1 : polynomial α) ≤ (0 : with_bot ℕ) :=
id                         └────┘      └────────┘         └──────┘ 
src                        └────┘      └────────┘          └──────┘ 
typ                        └────┘      └────────┘         └──────┘ 
doc                        └────┘      └────────┘
427  by rw [← C_1]; exact degree_C_le
id            └─┘         └─────────┘
src     └────┘└─┘  └────┘└─────────┘
typ     └────┘└─┘  └────┘└─────────┘
doc     └────┘     └────┘           
txt     └────┘     └────┘           
par     └────┘     └────┘           
pid       └──┘                     
st     └────────┘└───────────────────
428  
src  
typ  
doc  
txt  
par  
pid  
st   
429  lemma degree_eq_bot : degree p = ⊥ ↔ p = 0 :=
id                         └────┘      
src                        └────┘        
typ                        └────┘      
doc                        └────┘
430  ⟨λ h, by rw [degree, ← max_eq_sup_with_bot] at h;
id               └────┘    └─────────────────┘
src           └──┘└────┘└──┘└─────────────────┘└────┘
typ          └──┘└────┘└──┘└─────────────────┘└────┘
doc           └──┘└────┘└──┘                   └────┘
txt           └──┘      └──┘                   └────┘
par           └──┘      └──┘                   └────┘
pid             └┘      └──┘                   └───┘
st           └─────────┘└─────────────────────┘└──────
431    exact support_eq_empty.1 (max_eq_none.1 h),
id           └──────────────┘    └─────────┘   
src    └────┘└──────────────┘└─┘ └─────────┘└─┘ 
typ    └────┘└──────────────┘└─┘ └─────────┘└─┘
doc    └────┘                └─┘            └─┘ 
txt    └────┘                └─┘            └─┘ 
par    └────┘                └─┘            └─┘ 
pid                         └─┘            └─┘ 
st   ───────────────────────────────────────────┘
432  λ h, h.symm ▸ rfl⟩
id       └───┘  └─┘
src        └───┘  └─┘
typ      └───┘  └─┘
433  
434  lemma degree_eq_nat_degree (hp : p ≠ 0) : degree p = (nat_degree p : with_bot ℕ) :=
id                                           └────┘    └────────┘    └──────┘ 
src                                           └────┘     └────────┘     └──────┘ 
typ                                          └────┘    └────────┘    └──────┘ 
doc                                            └────┘      └────────┘
435  let ⟨n, hn⟩ :=
id   └─┘    └┘
typ  └─┘    └┘
436    classical.not_forall.1 (mt option.eq_none_iff_forall_not_mem.2 (mt degree_eq_bot.1 hp)) in
id     └──────────────────┘   └┘ └───────────────────────────────┘   └┘ └───────────┘  └┘
src    └──────────────────┘   └┘ └───────────────────────────────┘   └┘ └───────────┘
typ    └──────────────────┘   └┘ └───────────────────────────────┘   └┘ └───────────┘  └┘
437  have hn : degree p = some n := not_not.1 hn,
id             └────┘   └──┘      └─────┘
src            └────┘    └──┘      └─────┘
typ            └────┘   └──┘      └─────┘
doc            └────┘
438  by rw [nat_degree, hn]; refl
id          └────────┘  └┘
src     └──┘└────────┘└┘    └────
typ     └──┘└────────┘└┘└┘  └────
doc     └──┘└────────┘└┘    └────
txt     └──┘          └┘    └────
par     └──┘          └┘    └────
pid       └┘          └┘        
st     └─────────────┘└──┘└──────
439  
src  
typ  
doc  
txt  
par  
pid  
st   
440  lemma degree_eq_iff_nat_degree_eq {p : polynomial α} {n : ℕ} (hp : p ≠ 0) :
id                                          └────────┘                 
src                                         └────────┘                   
typ                                         └────────┘                 
doc                                         └────────┘
441    p.degree = n ↔ p.nat_degree = n :=
id     └─────┘    └─────────┘  
src     └─────┘      └─────────┘ 
typ    └─────┘    └─────────┘  
doc     └─────┘        └─────────┘
442  by rw [degree_eq_nat_degree hp, with_bot.coe_eq_coe]
id          └──────────────────┘ └┘  └─────────────────┘
src     └──┘└──────────────────┘  └┘└─────────────────┘└─
typ     └──┘└──────────────────┘└┘└┘└─────────────────┘└─
doc     └──┘                      └┘                   └─
txt     └──┘                      └┘                   └─
par     └──┘                      └┘                   └─
pid       └┘                      └┘                   
st     └──────────────────────────┘└───────────────────┘
443  
src  
typ  
doc  
txt  
par  
pid  
st   
444  lemma degree_eq_iff_nat_degree_eq_of_pos {p : polynomial α} {n : ℕ} (hn : n > 0) :
id                                                 └────────┘                 
src                                                └────────┘                   
typ                                                └────────┘                 
doc                                                └────────┘
445    p.degree = n ↔ p.nat_degree = n :=
id     └─────┘    └─────────┘  
src     └─────┘      └─────────┘ 
typ    └─────┘    └─────────┘  
doc     └─────┘        └─────────┘
446  begin
st   └─────
447    split,
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
st   ──────┘└─
448    { intro H, rwa ← degree_eq_iff_nat_degree_eq, rintro rfl,
id                      └─────────────────────────┘
src      └─────┘  └────┘└─────────────────────────┘  └────────┘
typ      └─────┘  └────┘└─────────────────────────┘  └────────┘
doc      └─────┘  └────┘                             └────────┘
txt      └─────┘  └────┘                             └────────┘
par      └─────┘  └────┘                             └────────┘
pid           └┘     └─┘                                   └──┘
st   ───┘└─────┘└─────────────────────────────────┘└──────────┘└─
449      rw degree_zero at H, exact option.no_confusion H },
id          └─────────┘             └─────────────────┘ 
src      └─┘└─────────┘└───┘  └────┘└─────────────────┘ 
typ      └─┘└─────────┘└───┘  └────┘└─────────────────┘
doc      └─┘           └───┘  └────┘                    
txt      └─┘           └───┘  └────┘                    
par      └─┘           └───┘  └────┘                    
pid                   └───┘                           
st   ──────────────────────┘└────────────────────────────┘└┘
450    { intro H, rwa degree_eq_iff_nat_degree_eq, rintro rfl,
id                    └─────────────────────────┘
src      └─────┘  └──┘└─────────────────────────┘  └────────┘
typ      └─────┘  └──┘└─────────────────────────┘  └────────┘
doc      └─────┘  └──┘                             └────────┘
txt      └─────┘  └──┘                             └────────┘
par      └─────┘  └──┘                             └────────┘
pid           └┘                                        └──┘
st   ──────────┘└───────────────────────────────┘└──────────┘└─
451      rw nat_degree_zero at H, rw H at hn, exact lt_irrefl _ hn }
id          └─────────────┘                        └───────┘   └┘
src      └─┘└─────────────┘└───┘  └─┘ └────┘  └────┘└───────┘└─┘  
typ      └─┘└─────────────┘└───┘  └─┘└────┘  └────┘└───────┘└─┘└┘
doc      └─┘               └───┘  └─┘ └────┘  └────┘         └─┘  
txt      └─┘               └───┘  └─┘ └────┘  └────┘         └─┘  
par      └─┘               └───┘  └─┘ └────┘  └────┘         └─┘  
pid                       └───┘     └────┘                └─┘  
st   ──────────────────────────┘└──────────┘└─────────────────────┘└─
452  end
st   ──┘
453  
454  lemma nat_degree_eq_of_degree_eq_some {p : polynomial α} {n : ℕ}
id                                              └────────┘        
src                                             └────────┘         
typ                                             └────────┘        
doc                                             └────────┘
455    (h : degree p = n) : nat_degree p = n :=
id          └────┘       └────────┘   
src         └────┘         └────────┘   
typ         └────┘       └────────┘   
doc         └────┘          └────────┘
456  have hp0 : p ≠ 0, from λ hp0, by rw hp0 at h; exact option.no_confusion h,
id                          └─┘        └─┘             └─────────────────┘ 
src                                  └─┘   └───┘  └────┘└─────────────────┘
typ                         └─┘     └─┘└─┘└───┘  └────┘└─────────────────┘
doc                                   └─┘   └───┘  └────┘                   
txt                                   └─┘   └───┘  └────┘                   
par                                   └─┘   └───┘  └────┘                   
pid                                        └───┘                          
st                                   └───────────────────────────────────────┘
457  option.some_inj.1 $ show (nat_degree p : with_bot ℕ) = n,
id   └─────────────┘          └────────┘    └──────┘    
src  └─────────────┘          └────────┘     └──────┘   
typ  └─────────────┘          └────────┘    └──────┘    
doc                            └────────┘
458    by rwa [← degree_eq_nat_degree hp0]
id               └──────────────────┘ └─┘
src       └─────┘└──────────────────┘   └─
typ       └─────┘└──────────────────┘└─┘└─
doc       └─────┘                       └─
txt       └─────┘                       └─
par       └─────┘                       └─
pid          └──┘                       
st       └──────────────────────────────┘
459  
src  
typ  
doc  
txt  
par  
pid  
st   
460  @[simp] lemma degree_le_nat_degree : degree p ≤ nat_degree p :=
id                                        └────┘   └────────┘ 
src                                       └────┘    └────────┘
typ                                       └────┘   └────────┘ 
doc    └──┘                               └────┘     └────────┘
461  begin
st   └─────
462    by_cases hp : p = 0, { rw hp, exact bot_le },
id                             └┘        └────┘
src    └───────┘  └─┘ └┘    └─┘    └────┘└────┘
typ    └───────┘  └─┘└┘    └─┘└┘  └────┘└────┘
doc    └───────┘  └─┘  └┘    └─┘    └────┘      
txt    └───────┘  └─┘  └┘    └─┘    └────┘      
par    └───────┘  └─┘  └┘    └─┘    └────┘      
pid              └─┘                       
st   ────────────────────┘└──┘└───┘└─────────────┘└┘
463    rw [degree_eq_nat_degree hp],
id         └──────────────────┘ └┘
src    └──┘└──────────────────┘  
typ    └──┘└──────────────────┘└┘
doc    └──┘                      
txt    └──┘                      
par    └──┘                      
pid      └┘                      
st   ────────────────────────────┘└──
464    exact le_refl _
id           └─────┘
src    └────┘└─────┘└─┘
typ    └────┘└─────┘└─┘
doc    └────┘       └─┘
txt    └────┘       └─┘
par    └────┘       └─┘
pid                └┘
st   ─────────────────┘
465  end
st   └─┘
466  
467  lemma nat_degree_eq_of_degree_eq [comm_semiring β] {q : polynomial β}
id                                     └───────────┘        └────────┘ 
src                                    └───────────┘         └────────┘
typ                                    └───────────┘        └────────┘ 
doc                                                          └────────┘
468    (h : degree p = degree q) : nat_degree p = nat_degree q :=
id          └────┘   └────┘     └────────┘   └────────┘ 
src         └────┘    └────┘      └────────┘    └────────┘
typ         └────┘   └────┘     └────────┘   └────────┘ 
doc         └────┘     └────┘      └────────┘     └────────┘
469  by unfold nat_degree; rw h
id                            
src     └───────────────┘  └─┘ 
typ     └───────────────┘  └─┘
doc     └───────────────┘  └─┘ 
txt     └───────────────┘  └─┘ 
par     └───────────────┘  └─┘ 
pid           └─────────┘     
st     └─────────────────────┘
470  
src  
typ  
doc  
txt  
par  
pid  
st   
471  lemma le_degree_of_ne_zero (h : coeff p n ≠ 0) : (n : with_bot ℕ) ≤ degree p :=
id                                   └───┘             └──────┘    └────┘ 
src                                  └───┘                └──────┘    └────┘
typ                                  └───┘             └──────┘    └────┘ 
doc                                  └───┘                               └────┘
472  show @has_le.le (with_bot ℕ) _ (some n : with_bot ℕ) (p.support.sup some : with_bot ℕ),
id         └───────┘  └──────┘      └──┘    └──────┘    └──────┘└──┘ └──┘   └──────┘ 
src        └───────┘  └──────┘      └──┘     └──────┘     └──────┘└──┘ └──┘   └──────┘ 
typ        └───────┘  └──────┘      └──┘    └──────┘    └──────┘└──┘ └──┘   └──────┘ 
doc                                                                 └──┘
473  from finset.le_sup (finsupp.mem_support_iff.2 h)
id        └───────────┘  └─────────────────────┘  
src       └───────────┘  └─────────────────────┘
typ       └───────────┘  └─────────────────────┘  
474  
475  lemma le_nat_degree_of_ne_zero (h : coeff p n ≠ 0) : n ≤ nat_degree p :=
id                                       └───┘           └────────┘ 
src                                      └───┘              └────────┘
typ                                      └───┘           └────────┘ 
doc                                      └───┘                └────────┘
476  begin
st   └─────
477    rw [← with_bot.coe_le_coe, ← degree_eq_nat_degree],
id           └─────────────────┘    └──────────────────┘
src    └────┘└─────────────────┘└──┘└──────────────────┘
typ    └────┘└─────────────────┘└──┘└──────────────────┘
doc    └────┘                   └──┘                    
txt    └────┘                   └──┘                    
par    └────┘                   └──┘                    
pid      └──┘                   └──┘                    
st   ──────────────────────────┘└──────────────────────┘└──
478    exact le_degree_of_ne_zero h,
id           └──────────────────┘ 
src    └────┘└──────────────────┘
typ    └────┘└──────────────────┘
doc    └────┘                    
txt    └────┘                    
par    └────┘                    
pid                             
st   ─────────────────────────────┘└─
479    { assume h, subst h, exact h rfl }
id                                └─┘
src      └──────┘  └────┘   └────┘ └─┘
typ      └──────┘  └────┘  └────┘└─┘
doc      └──────┘  └────┘   └────┘    
txt      └──────┘  └────┘   └────┘    
par      └──────┘  └────┘   └────┘    
pid      └──────┘                   
st   ───────────┘└───────┘└────────────┘└─
480  end
st   ──┘
481  
482  lemma degree_le_degree (h : coeff q (nat_degree p) ≠ 0) : degree p ≤ degree q :=
id                               └───┘   └────────┘         └────┘   └────┘ 
src                              └───┘    └────────┘          └────┘    └────┘
typ                              └───┘   └────────┘         └────┘   └────┘ 
doc                              └───┘    └────────┘           └────┘     └────┘
483  begin
st   └─────
484    by_cases hp : p = 0,
id                    
src    └───────┘  └─┘ └┘
typ    └───────┘  └─┘└┘
doc    └───────┘  └─┘  └┘
txt    └───────┘  └─┘  └┘
par    └───────┘  └─┘  └┘
pid              └─┘  
st   ────────────────────┘└─
485    { rw hp, exact bot_le },
id          └┘        └────┘
src      └─┘    └────┘└────┘
typ      └─┘└┘  └────┘└────┘
doc      └─┘    └────┘      
txt      └─┘    └────┘      
par      └─┘    └────┘      
pid                       
st   ───┘└───┘└─────────────┘└┘
486    { rw degree_eq_nat_degree hp, exact le_degree_of_ne_zero h }
id          └──────────────────┘ └┘        └──────────────────┘ 
src      └─┘└──────────────────┘    └────┘└──────────────────┘ 
typ      └─┘└──────────────────┘└┘  └────┘└──────────────────┘
doc      └─┘                        └────┘                     
txt      └─┘                        └────┘                     
par      └─┘                        └────┘                     
pid                                                          
st   ─────────────────────────────┘└─────────────────────────────┘└─
487  end
st   ──┘
488  
489  @[simp] lemma nat_degree_C (a : α) : nat_degree (C a) = 0 :=
id                                       └────────┘     
src                                       └────────┘      
typ                                      └────────┘     
doc    └──┘                               └────────┘  
490  begin
st   └─────
491    by_cases ha : a = 0,
id                    
src    └───────┘  └─┘ └┘
typ    └───────┘  └─┘└┘
doc    └───────┘  └─┘  └┘
txt    └───────┘  └─┘  └┘
par    └───────┘  └─┘  └┘
pid              └─┘  
st   ────────────────────┘└─
492    { have : C a = 0, { rw [ha, C_0] },
id                           └┘  └─┘
src      └─────┘  └┘    └──┘  └┘└─┘└┘
typ      └─────┘ └┘    └──┘└┘└┘└─┘└┘
doc      └─────┘  └┘    └──┘  └┘   └┘
txt      └─────┘   └┘    └──┘  └┘   └┘
par      └─────┘   └┘    └──┘  └┘   └┘
pid      └───┘└┘         └┘  └┘   
st   ───┘└────────────┘└──┘└────┘└───┘└┘
493      rw [nat_degree, degree_eq_bot.2 this],
id           └────────┘  └───────────┘   └──┘
src      └──┘└────────┘└┘└───────────┘└─┘    
typ      └──┘└────────┘└┘└───────────┘└─┘└──┘
doc      └──┘└────────┘└┘             └─┘    
txt      └──┘          └┘             └─┘    
par      └──┘          └┘             └─┘    
pid        └┘          └┘             └─┘    
st   ─────────────────┘└────────────────────┘└──
494      refl },
src      └───┘
typ      └───┘
doc      └───┘
txt      └───┘
par      └───┘
pid          
st   ────────┘└┘
495    { rw [nat_degree, degree_C ha], refl }
id           └────────┘  └──────┘ └┘
src      └──┘└────────┘└┘└──────┘    └───┘
typ      └──┘└────────┘└┘└──────┘└┘  └───┘
doc      └──┘└────────┘└┘            └───┘
txt      └──┘          └┘            └───┘
par      └──┘          └┘            └───┘
pid        └┘          └┘                
st   ─────────────────┘└───────────┘└──────┘└─
496  end
st   ──┘
497  
498  @[simp] lemma nat_degree_one : nat_degree (1 : polynomial α) = 0 := nat_degree_C 1
id                                  └────────┘      └────────┘         └──────────┘
src                                 └────────┘      └────────┘          └──────────┘
typ                                 └────────┘      └────────┘         └──────────┘
doc    └──┘                         └────────┘      └────────┘
499  
500  @[simp] lemma nat_degree_nat_cast (n : ℕ) : nat_degree (n : polynomial α) = 0 :=
id                                              └────────┘     └────────┘   
src                                             └────────┘      └────────┘    
typ                                             └────────┘     └────────┘   
doc    └──┘                                      └────────┘      └────────┘
501  by simp [nat_cast_eq_C]
id            └───────────┘
src     └────┘└───────────┘└─
typ     └────┘└───────────┘└─
doc     └────┘             └─
txt     └────┘             └─
par     └────┘             └─
pid                      
st     └─────────────────────
502  
src  
typ  
doc  
txt  
par  
pid  
st   
503  @[simp] lemma degree_monomial (n : ℕ) (ha : a ≠ 0) : degree (C a * X ^ n) = n :=
id                                                     └────┘          
src                                                     └────┘           
typ                                                    └────┘          
doc    └──┘                                               └────┘       
504  by rw [← single_eq_C_mul_X, degree, support_single_ne_zero ha]; refl
id            └───────────────┘  └────┘  └────────────────────┘ └┘
src     └────┘└───────────────┘└┘└────┘└┘└────────────────────┘    └────
typ     └────┘└───────────────┘└┘└────┘└┘└────────────────────┘└┘  └────
doc     └────┘                 └┘└────┘└┘                          └────
txt     └────┘                 └┘      └┘                          └────
par     └────┘                 └┘      └┘                          └────
pid       └──┘                 └┘      └┘                              
st     └──────────────────────┘└──────┘└─────────────────────────┘└──────
505  
src  
typ  
doc  
txt  
par  
pid  
st   
506  lemma degree_monomial_le (n : ℕ) (a : α) : degree (C a * X ^ n) ≤ n :=
id                                            └────┘          
src                                            └────┘           
typ                                           └────┘          
doc                                             └────┘       
507  if h : a = 0 then by rw [h, C_0, zero_mul]; exact bot_le else le_of_eq (degree_monomial n h)
id   └┘                       └─┘  └──────┘         └────┘      └──────┘  └─────────────┘  
src  └┘                  └──┘ └┘└─┘└┘└──────┘  └────┘└────┘     └──────┘  └─────────────┘
typ  └┘                 └──┘└┘└─┘└┘└──────┘  └────┘└────┘     └──────┘  └─────────────┘  
doc                       └──┘ └┘   └┘          └────┘      
txt                       └──┘ └┘   └┘          └────┘      
par                       └──┘ └┘   └┘          └────┘      
pid                         └┘ └┘   └┘                     
st                       └────┘└───┘└────────┘└─────────────┘
508  
509  lemma coeff_eq_zero_of_degree_lt (h : degree p < n) : coeff p n = 0 :=
id                                         └────┘       └───┘   
src                                        └────┘         └───┘     
typ                                        └────┘       └───┘   
doc                                        └────┘          └───┘
510  not_not.1 (mt le_degree_of_ne_zero (not_le_of_gt h))
id   └─────┘   └┘ └──────────────────┘  └──────────┘ 
src  └─────┘   └┘ └──────────────────┘  └──────────┘
typ  └─────┘   └┘ └──────────────────┘  └──────────┘ 
511  
512  lemma coeff_eq_zero_of_nat_degree_lt {p : polynomial α} {n : ℕ} (h : p.nat_degree < n) :
id                                             └────────┘               └─────────┘  
src                                            └────────┘                 └─────────┘ 
typ                                            └────────┘               └─────────┘  
doc                                            └────────┘                  └─────────┘
513    p.coeff n = 0 :=
id     └────┘  
src     └────┘   
typ    └────┘  
doc     └────┘
514  begin
st   └─────
515    apply coeff_eq_zero_of_degree_lt,
id           └────────────────────────┘
src    └────┘└────────────────────────┘
typ    └────┘└────────────────────────┘
doc    └────┘
txt    └────┘
par    └────┘
pid         
st   ─────────────────────────────────┘└─
516    by_cases hp : p = 0,
id                    
src    └───────┘  └─┘ └┘
typ    └───────┘  └─┘└┘
doc    └───────┘  └─┘  └┘
txt    └───────┘  └─┘  └┘
par    └───────┘  └─┘  └┘
pid              └─┘  
st   ────────────────────┘└─
517    { subst hp, exact with_bot.bot_lt_coe n },
id             └┘        └─────────────────┘ 
src      └────┘    └────┘└─────────────────┘ 
typ      └────┘└┘  └────┘└─────────────────┘
doc      └────┘    └────┘                    
txt      └────┘    └────┘                    
par      └────┘    └────┘                    
pid                                        
st   ───┘└──────┘└────────────────────────────┘└┘
518    { rwa [degree_eq_nat_degree hp, with_bot.coe_lt_coe] }
id            └──────────────────┘ └┘  └─────────────────┘
src      └───┘└──────────────────┘  └┘└─────────────────┘└┘
typ      └───┘└──────────────────┘└┘└┘└─────────────────┘└┘
doc      └───┘                      └┘                   └┘
txt      └───┘                      └┘                   └┘
par      └───┘                      └┘                   └┘
pid         └┘                      └┘                   
st   ───────────────────────────────┘└───────────────────┘└─
519  end
st   ──┘
520  
521  -- TODO find a home (this file)
522  @[simp] lemma finset_sum_coeff (s : finset β) (f : β → polynomial α) (n : ℕ) :
id                                       └────┘           └────────┘        
src                                      └────┘             └────────┘         
typ                                      └────┘           └────────┘        
doc    └──┘                              └────┘             └────────┘
523    coeff (s.sum f) n = s.sum (λ b, coeff (f b) n) :=
id     └───┘  └──┘     └──┘      └───┘     
src    └───┘   └──┘        └──┘       └───┘
typ    └───┘  └──┘     └──┘      └───┘     
doc    └───┘                           └───┘
524  (s.sum_hom (λ q : polynomial α, q.coeff n)).symm
id    └──────┘        └────────┘   └────┘   └──┘
src    └──────┘        └────────┘     └────┘    └──┘
typ   └──────┘        └────────┘   └────┘   └──┘
doc                    └────────┘     └────┘
525  
526  -- We need the explicit `decidable` argument here because an exotic one shows up in a moment!
527  lemma ite_le_nat_degree_coeff (p : polynomial α) (n : ℕ) (I : decidable (n < 1 + nat_degree p)) :
id                                      └────────┘               └───────┘       └────────┘ 
src                                     └────────┘                └───────┘        └────────┘
typ                                     └────────┘               └───────┘       └────────┘ 
doc                                     └────────┘                                    └────────┘
528    @ite (n < 1 + nat_degree p) I _ (coeff p n) 0 = coeff p n :=
id      └─┘       └────────┘       └───┘       └───┘  
src     └─┘        └────────┘         └───┘         └───┘
typ     └─┘       └────────┘       └───┘       └───┘  
doc                  └────────┘         └───┘          └───┘
529  begin
st   └─────
530    split_ifs,
src    └───────┘
typ    └───────┘
doc    └───────┘
txt    └───────┘
par    └───────┘
st   ──────────┘└─
531    { refl },
src      └───┘
typ      └───┘
doc      └───┘
txt      └───┘
par      └───┘
pid          
st   ───┘└───┘└┘
532    { exact (coeff_eq_zero_of_nat_degree_lt (not_le.1 (λ w, h (nat.lt_one_add_iff.2 w)))).symm, }
id              └────────────────────────────┘  └────┘           └────────────────┘
src      └────┘ └────────────────────────────┘ └────┘└─┘  └──┘  └────────────────┘└─┘ └───────┘
typ      └────┘ └────────────────────────────┘ └────┘└─┘  └──┘ └────────────────┘└─┘ └───────┘
doc      └────┘                                      └─┘  └──┘                    └─┘ └───────┘
txt      └────┘                                      └─┘  └──┘                    └─┘ └───────┘
par      └────┘                                      └─┘  └──┘                    └─┘ └───────┘
pid                                                 └─┘  └──┘                    └─┘ └──────┘
st   ───────────────────────────────────────────────────────────────────────────────────────────┘└───
533  end
st   ──┘
534  
535  lemma as_sum (p : polynomial α) :
id                     └────────┘ 
src                    └────────┘
typ                    └────────┘ 
doc                    └────────┘
536    p = (range (p.nat_degree + 1)).sum (λ i, C (p.coeff i) * X^i) :=
id        └───┘  └─────────┘     └─┘         └────┘    
src        └───┘   └─────────┘     └─┘           └────┘     
typ       └───┘  └─────────┘     └─┘         └────┘    
doc         └───┘   └─────────┘                    └────┘      
537  begin
st   └─────
538    ext n,
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
pid       └┘
st   ──────┘└─
539    simp only [add_comm, coeff_X_pow, coeff_C_mul, finset.mem_range,
id                └──────┘  └─────────┘  └─────────┘  └──────────────┘
src    └─────────┘└──────┘└┘└─────────┘└┘└─────────┘└┘└──────────────┘└─
typ    └─────────┘└──────┘└┘└─────────┘└┘└─────────┘└┘└──────────────┘└─
doc    └─────────┘        └┘           └┘           └┘                └─
txt    └─────────┘        └┘           └┘           └┘                └─
par    └─────────┘        └┘           └┘           └┘                └─
pid        └──┘└┘        └┘           └┘           └┘                └─
st   ───────────────────────────────────────────────────────────────────
540      finset.sum_mul_boole, finset_sum_coeff, ite_le_nat_degree_coeff],
id       └──────────────────┘  └──────────────┘  └─────────────────────┘
src  ───┘└──────────────────┘└┘└──────────────┘└┘└─────────────────────┘
typ  ───┘└──────────────────┘└┘└──────────────┘└┘└─────────────────────┘
doc  ───┘                    └┘                └┘                       
txt  ───┘                    └┘                └┘                       
par  ───┘                    └┘                └┘                       
pid  ───┘                    └┘                └┘                       
st   ───────────────────────────────────────────────────────────────────┘└─
541  end
st   ──┘
542  
543  lemma monic.as_sum {p : polynomial α} (hp : p.monic) :
id                           └────────┘         └────┘
src                          └────────┘           └────┘
typ                          └────────┘         └────┘
doc                          └────────┘           └────┘
544    p = X^(p.nat_degree) + ((finset.range p.nat_degree).sum $ λ i, C (p.coeff i) * X^i) :=
id        └─────────┘     └──────────┘ └─────────┘ └─┘          └────┘    
src         └─────────┘     └──────────┘  └─────────┘ └─┘            └────┘     
typ       └─────────┘     └──────────┘ └─────────┘ └─┘          └────┘    
doc           └─────────┘      └──────────┘  └─────────┘                └────┘      
545  begin
st   └─────
546    conv_lhs { rw [p.as_sum, finset.sum_range_succ] },
id                              └───────────────────┘
src    └─────────┘└──┘        └┘└───────────────────┘└┘
typ    └─────────┘└──┘└──────┘└┘└───────────────────┘└┘
txt    └─────────┘└──┘        └┘                     └┘
par    └─────────┘└──┘        └┘                     └┘
pid            └────┘        └┘                     └─┘
st   ───────────┘└───────────┘└─────────────────────┘ └┘
547    suffices : C (p.coeff p.nat_degree) = 1,
id                  └─────┘ └──────────┘  
src    └─────────┘ └─────┘└──────────┘└┘└┘
typ    └─────────┘ └─────┘└──────────┘└┘└┘
doc    └─────────┘ └─────┘└──────────┘└┘ └┘
txt    └─────────┘                     └┘ └┘
par    └─────────┘                     └┘ └┘
pid    └───────┘└┘                     └┘ 
st   ────────────────────────────────────────┘└─
548    { rw [this, one_mul] },
id           └──┘  └─────┘
src      └──┘    └┘└─────┘└┘
typ      └──┘└──┘└┘└─────┘└┘
doc      └──┘    └┘       └┘
txt      └──┘    └┘       └┘
par      └──┘    └┘       └┘
pid        └┘    └┘       
st   ───┘└──────┘└───────┘└┘
549    exact congr_arg C hp
id           └───────┘  └┘
src    └────┘└───────┘  
typ    └────┘└───────┘└┘
doc    └────┘           
txt    └────┘            
par    └────┘            
pid                     
st   ──────────────────────┘
550  end
st   └─┘
551  
552  section map
553  variables [comm_semiring β]
id              └───────────┘
src             └───────────┘
typ             └───────────┘
554  variables (f : α → β)
555  
556  /-- `map f p` maps a polynomial `p` across a ring hom `f` -/
557  def map : polynomial α → polynomial β := eval₂ (C ∘ f) X
id             └────────┘    └────────┘     └───┘      
src            └────────┘     └────────┘      └───┘       
typ            └────────┘    └────────┘     └───┘      
doc            └────────┘     └────────┘      └───┘        
558  
559  variables [is_semiring_hom f]
id              └─────────────┘
src             └─────────────┘
typ             └─────────────┘
doc             └─────────────┘
560  
561  @[simp] lemma map_C : (C a).map f = C (f a) := eval₂_C _ _
id                            └─┘            └─────┘
src                            └─┘               └─────┘
typ                           └─┘            └─────┘
doc    └──┘                    └─┘      
562  
563  @[simp] lemma map_X : X.map f = X := eval₂_X _ _
id                         └──┘       └─────┘
src                        └──┘        └─────┘
typ                        └──┘       └─────┘
doc    └──┘                └──┘     
564  
565  @[simp] lemma map_zero : (0 : polynomial α).map f = 0 :=  eval₂_zero _ _
id                                 └────────┘  └─┘          └────────┘
src                                └────────┘   └─┘           └────────┘
typ                                └────────┘  └─┘          └────────┘
doc    └──┘                        └────────┘   └─┘
566  
567  @[simp] lemma map_add : (p + q).map f = p.map f + q.map f := eval₂_add _ _
id                               └─┘    └──┘   └──┘     └───────┘
src                                └─┘      └──┘     └──┘      └───────┘
typ                              └─┘    └──┘   └──┘     └───────┘
doc    └──┘                         └─┘       └──┘      └──┘
568  
569  @[simp] lemma map_one : (1 : polynomial α).map f = 1 := eval₂_one _ _
id                                └────────┘  └─┘         └───────┘
src                               └────────┘   └─┘          └───────┘
typ                               └────────┘  └─┘         └───────┘
doc    └──┘                       └────────┘   └─┘
570  
571  @[simp] lemma map_mul : (p * q).map f = p.map f * q.map f := eval₂_mul _ _
id                               └─┘    └──┘   └──┘     └───────┘
src                                └─┘      └──┘     └──┘      └───────┘
typ                              └─┘    └──┘   └──┘     └───────┘
doc    └──┘                         └─┘       └──┘      └──┘
572  
573  instance map.is_semiring_hom : is_semiring_hom (map f) := eval₂.is_semiring_hom _ _
id                                  └─────────────┘  └─┘      └───────────────────┘
src                                 └─────────────┘  └─┘       └───────────────────┘
typ                                 └─────────────┘  └─┘      └───────────────────┘
doc                                 └─────────────┘  └─┘
574  
575  @[simp] lemma map_pow (n : ℕ) : (p ^ n).map f = p.map f ^ n := eval₂_pow _ _ _
id                                      └─┘    └──┘       └───────┘
src                                       └─┘      └──┘         └───────┘
typ                                     └─┘    └──┘       └───────┘
doc    └──┘                                 └─┘       └──┘
576  
577  lemma coeff_map (n : ℕ) : coeff (p.map f) n = f (coeff p n) :=
id                            └───┘  └──┘       └───┘  
src                           └───┘   └──┘          └───┘
typ                           └───┘  └──┘       └───┘  
doc                            └───┘   └──┘           └───┘
578  begin
st   └─────
579    rw [map, eval₂, coeff_sum],
id         └─┘  └───┘  └───────┘
src    └──┘└─┘└┘└───┘└┘└───────┘
typ    └──┘└─┘└┘└───┘└┘└───────┘
doc    └──┘└─┘└┘└───┘└┘         
txt    └──┘   └┘     └┘         
par    └──┘   └┘     └┘         
pid      └┘   └┘     └┘         
st   ────────┘└─────┘└─────────┘└──
580    conv_rhs { rw [← sum_C_mul_X_eq p, coeff_sum, finsupp.sum,
id                      └────────────┘   └───────┘  └─────────┘
src    └─────────┘└────┘└────────────┘ └┘└───────┘└┘└─────────┘└─
typ    └─────────┘└────┘└────────────┘└┘└───────┘└┘└─────────┘└─
doc                                                  └─────────┘
txt    └─────────┘└────┘               └┘         └┘           └─
par    └─────────┘└────┘               └┘         └┘           └─
pid            └──────┘               └┘         └┘           └─
st   ───────────┘└─────────────────────┘└─────────┘└───────────┘└─
581      ← p.support.sum_hom f], },
id         └───────────────┘ 
src  ─────┘└───────────────┘ └─┘
typ  ─────┘└───────────────┘└─┘
txt  ─────┘                  └─┘
par  ─────┘                  └─┘
pid  ─────┘                  └──┘
st   ────────────────────────┘ └──┘
582    refine finset.sum_congr rfl (λ x hx, _),
id            └──────────────┘ └─┘
src    └─────┘└──────────────┘└─┘  └───────┘
typ    └─────┘└──────────────┘└─┘  └───────┘
doc    └─────┘                     └───────┘
txt    └─────┘                     └───────┘
par    └─────┘                     └───────┘
pid                               └───────┘
st   ────────────────────────────────────────┘└─
583    simp [function.comp, coeff_C_mul_X, is_semiring_hom.map_mul f],
id           └───────────┘  └───────────┘  └─────────────────────┘ 
src    └────┘└───────────┘└┘└───────────┘└┘└─────────────────────┘ 
typ    └────┘└───────────┘└┘└───────────┘└┘└─────────────────────┘
doc    └────┘             └┘             └┘                        
txt    └────┘             └┘             └┘                        
par    └────┘             └┘             └┘                        
pid                     └┘             └┘                        
st   ───────────────────────────────────────────────────────────────┘└─
584    split_ifs; simp [is_semiring_hom.map_zero f],
id                      └──────────────────────┘ 
src    └───────┘  └────┘└──────────────────────┘ 
typ    └───────┘  └────┘└──────────────────────┘
doc    └───────┘  └────┘                         
txt    └───────┘  └────┘                         
par    └───────┘  └────┘                         
pid                                            
st   ─────────────────────────────────────────────┘└─
585  end
st   ──┘
586  
587  lemma map_map {γ : Type*} [comm_semiring γ] (g : β → γ) [is_semiring_hom g]
id                              └───────────┘              └─────────────┘ 
src                             └───────────┘                 └─────────────┘
typ                             └───────────┘              └─────────────┘ 
doc                                                           └─────────────┘
588    (p : polynomial α) : (p.map f).map g = p.map (λ x, g (f x)) :=
id          └────────┘      └──┘  └─┘    └──┘         
src         └────────┘        └──┘   └─┘      └──┘
typ         └────────┘      └──┘  └─┘    └──┘         
doc         └────────┘        └──┘   └─┘       └──┘
589  ext (by simp [coeff_map])
id   └─┘           └───────┘
src  └─┘     └────┘└───────┘
typ  └─┘     └────┘└───────┘
doc          └────┘         
txt          └────┘         
par          └────┘         
pid                       
st          └───────────────┘
590  
591  lemma eval₂_map {γ : Type*} [comm_semiring γ] (g : β → γ) [is_semiring_hom g] (x : γ) :
id                                └───────────┘              └─────────────┘        
src                               └───────────┘                 └─────────────┘
typ                               └───────────┘              └─────────────┘        
doc                                                             └─────────────┘
592    (p.map f).eval₂ g x = p.eval₂ (λ y, g (f y)) x :=
id      └──┘  └───┘     └────┘            
src      └──┘   └───┘        └────┘
typ     └──┘  └───┘     └────┘            
doc      └──┘   └───┘         └────┘
593  polynomial.induction_on p
id   └─────────────────────┘ 
src  └─────────────────────┘
typ  └─────────────────────┘ 
594    (by simp)
src        └──┘
typ        └──┘
doc        └──┘
txt        └──┘
par        └──┘
st        └───┘
595    (by simp [is_semiring_hom.map_add f] {contextual := tt})
id               └─────────────────────┘                  └┘
src        └────┘└─────────────────────┘ └┘ └────────────┘└┘
typ        └────┘└─────────────────────┘└┘ └────────────┘└┘
doc        └────┘                        └┘ └────────────┘  
txt        └────┘                        └┘ └────────────┘  
par        └────┘                        └┘ └────────────┘  
pid                                     └────────────┘  
st        └──────────────────────────────────────────────────┘
596    (by simp [is_semiring_hom.map_mul f,
id               └─────────────────────┘ 
src        └────┘└─────────────────────┘ └─
typ        └────┘└─────────────────────┘└─
doc        └────┘                        └─
txt        └────┘                        └─
par        └────┘                        └─
pid                                    └─
st        └─────────────────────────────────
597      is_semiring_hom.map_pow f, pow_succ', (mul_assoc _ _ _).symm] {contextual := tt})
id       └─────────────────────┘   └───────┘   └───────┘                             └┘
src  ───┘└─────────────────────┘ └┘└───────┘└┘ └───────┘└────────────┘ └────────────┘└┘
typ  ───┘└─────────────────────┘└┘└───────┘└┘ └───────┘└────────────┘ └────────────┘└┘
doc  ───┘                        └┘         └┘          └────────────┘ └────────────┘  
txt  ───┘                        └┘         └┘          └────────────┘ └────────────┘  
par  ───┘                        └┘         └┘          └────────────┘ └────────────┘  
pid  ───┘                        └┘         └┘          └───────────┘ └────────────┘  
st   ───────────────────────────────────────────────────────────────────────────────────┘
598  
599  lemma eval_map (x : β) : (p.map f).eval x = p.eval₂ f x := eval₂_map _ _ _
id                            └──┘  └──┘    └────┘      └───────┘
src                             └──┘   └──┘      └────┘        └───────┘
typ                           └──┘  └──┘    └────┘      └───────┘
doc                             └──┘   └──┘       └────┘
600  
601  @[simp] lemma map_id : p.map id = p := by simp [id, polynomial.ext_iff, coeff_map]
id                          └──┘ └┘               └┘  └────────────────┘  └───────┘
src                          └──┘ └┘          └────┘└┘└┘└────────────────┘└┘└───────┘└─
typ                         └──┘ └┘         └────┘└┘└┘└────────────────┘└┘└───────┘└─
doc    └──┘                  └──┘              └────┘  └┘                  └┘         └─
txt                                            └────┘  └┘                  └┘         └─
par                                            └────┘  └┘                  └┘         └─
pid                                                  └┘                  └┘         
st                                            └─────────────────────────────────────────
602  
src  
typ  
doc  
txt  
par  
pid  
st   
603  lemma mem_map_range {p : polynomial β} :
id                            └────────┘ 
src                           └────────┘
typ                           └────────┘ 
doc                           └────────┘
604    p ∈ set.range (map f) ↔ ∀ n, p.coeff n ∈ (set.range f) :=
id       └───────┘  └─┘        └────┘    └───────┘ 
src       └───────┘  └─┘           └────┘     └───────┘
typ      └───────┘  └─┘        └────┘    └───────┘ 
doc        └───────┘  └─┘            └────┘      └───────┘
605  begin
st   └─────
606    split,
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
st   ──────┘└─
607    { rintro ⟨p, rfl⟩ n, rw coeff_map, exact set.mem_range_self _ },
id                             └───────┘        └────────────────┘
src      └───────────────┘  └─┘└───────┘  └────┘└────────────────┘└─┘
typ      └───────────────┘  └─┘└───────┘  └────┘└────────────────┘└─┘
doc      └───────────────┘  └─┘           └────┘                  └─┘
txt      └───────────────┘  └─┘           └────┘                  └─┘
par      └───────────────┘  └─┘           └────┘                  └─┘
pid            └─────────┘                                      └┘
st   ───┘└───────────────┘└────────────┘└───────────────────────────┘└┘
608    { intro h, rw p.as_sum,
src      └─────┘  └─┘
typ      └─────┘  └─┘└──────┘
doc      └─────┘  └─┘
txt      └─────┘  └─┘
par      └─────┘  └─┘
pid           └┘    
st   ──────────┘└───────────┘└─
609      apply is_add_submonoid.finset_sum_mem,
id             └─────────────────────────────┘
src      └────┘└─────────────────────────────┘
typ      └────┘└─────────────────────────────┘
doc      └────┘└─────────────────────────────┘
txt      └────┘
par      └────┘
pid           
st   ────────────────────────────────────────┘└─
610      intros i hi,
src      └─────────┘
typ      └─────────┘
doc      └─────────┘
txt      └─────────┘
par      └─────────┘
pid            └───┘
st   ──────────────┘└─
611      rcases h i with ⟨c, hc⟩,
id               
src      └─────┘  └───────────┘
typ      └─────┘└───────────┘
doc      └─────┘  └───────────┘
txt      └─────┘  └───────────┘
par      └─────┘  └───────────┘
pid              └───────────┘
st   ──────────────────────────┘└─
612      use [C c * X^i],
id               
src      └───┘  
typ      └───┘
doc      └───┘    
txt      └───┘      
par      └───┘      
pid         └┘      
st   ──────────────────┘└─
613      rw [map_mul, map_C, hc, map_pow, map_X] }
id           └─────┘  └───┘  └┘  └─────┘  └───┘
src      └──┘└─────┘└┘└───┘└┘  └┘└─────┘└┘└───┘└┘
typ      └──┘└─────┘└┘└───┘└┘└┘└┘└─────┘└┘└───┘└┘
doc      └──┘       └┘     └┘  └┘       └┘     └┘
txt      └──┘       └┘     └┘  └┘       └┘     └┘
par      └──┘       └┘     └┘  └┘       └┘     └┘
pid        └┘       └┘     └┘  └┘       └┘     
st   ──────────────┘└─────┘└──┘└───────┘└─────┘└─
614  end
st   ──┘
615  
616  end map
617  
618  section
619  variables {γ : Type*} [comm_semiring β] [comm_semiring γ]
id                          └───────────┘     └───────────┘
src                         └───────────┘     └───────────┘
typ                         └───────────┘     └───────────┘
620  variables (f : α → β) (g : β → γ) [is_semiring_hom f] [is_semiring_hom g] (p)
id                                      └─────────────┘     └─────────────┘
src                                     └─────────────┘     └─────────────┘
typ                                     └─────────────┘     └─────────────┘
doc                                     └─────────────┘     └─────────────┘
621  
622  lemma hom_eval₂ (x : β) : g (p.eval₂ f x) = p.eval₂ (g ∘ f) (g x) :=
id                              └────┘     └────┘        
src                                └────┘        └────┘    
typ                             └────┘     └────┘        
doc                                └────┘         └────┘
623  begin
st   └─────
624    apply polynomial.induction_on p; clear p,
id           └─────────────────────┘ 
src    └────┘└─────────────────────┘   └─────┘
typ    └────┘└─────────────────────┘  └─────┘
doc    └────┘                          └─────┘
txt    └────┘                          └─────┘
par    └────┘                          └─────┘
pid                                        └┘
st   ─────────────────────────────────────────┘└─
625    { intros a, rw [eval₂_C, eval₂_C] },
id                     └─────┘  └─────┘
src      └──────┘  └──┘└─────┘└┘└─────┘└┘
typ      └──────┘  └──┘└─────┘└┘└─────┘└┘
doc      └──────┘  └──┘       └┘       └┘
txt      └──────┘  └──┘       └┘       └┘
par      └──────┘  └──┘       └┘       └┘
pid            └┘    └┘       └┘       
st   ───┘└──────┘└───────────┘└───────┘└┘
626    { intros p q hp hq, simp only [hp, hq, eval₂_add, is_semiring_hom.map_add g] },
id                                    └┘  └┘  └───────┘  └─────────────────────┘ 
src      └──────────────┘  └─────────┘  └┘  └┘└───────┘└┘└─────────────────────┘ └┘
typ      └──────────────┘  └─────────┘└┘└┘└┘└┘└───────┘└┘└─────────────────────┘└┘
doc      └──────────────┘  └─────────┘  └┘  └┘         └┘                        └┘
txt      └──────────────┘  └─────────┘  └┘  └┘         └┘                        └┘
par      └──────────────┘  └─────────┘  └┘  └┘         └┘                        └┘
pid            └────────┘      └──┘└┘  └┘  └┘         └┘                        
st   ───┘└──────────────┘└─────────────────────────────────────────────────────────┘└┘
627    { intros n a ih,
src      └───────────┘
typ      └───────────┘
doc      └───────────┘
txt      └───────────┘
par      └───────────┘
pid            └─────┘
st   ────────────────┘└─
628      replace ih := congr_arg (λ y, y * g x) ih,
id                     └───────┘             └┘
src      └────────────┘└───────┘  └──┘   └┘
typ      └────────────┘└───────┘  └──┘ └┘└┘
doc      └────────────┘           └──┘    └┘
txt      └────────────┘           └──┘    └┘
par      └────────────┘           └──┘    └┘
pid             └─┘└─┘           └──┘    └┘
st   ────────────────────────────────────────────┘└─
629      simpa [pow_succ', is_semiring_hom.map_mul g, (mul_assoc _ _ _).symm,
id              └───────┘  └─────────────────────┘    └───────┘
src      └─────┘└───────┘└┘└─────────────────────┘ └┘ └───────┘└─────────────
typ      └─────┘└───────┘└┘└─────────────────────┘└┘ └───────┘└─────────────
doc      └─────┘         └┘                        └┘          └─────────────
txt      └─────┘         └┘                        └┘          └─────────────
par      └─────┘         └┘                        └┘          └─────────────
pid                    └┘                        └┘          └─────────────
st   ─────────────────────────────────────────────────────────────────────────
630        eval₂_C, eval₂_mul, eval₂_X] using ih }
id         └─────┘  └───────┘  └─────┘        └┘
src  ─────┘└─────┘└┘└───────┘└┘└─────┘└──────┘  
typ  ─────┘└─────┘└┘└───────┘└┘└─────┘└──────┘└┘
doc  ─────┘       └┘         └┘       └──────┘  
txt  ─────┘       └┘         └┘       └──────┘  
par  ─────┘       └┘         └┘       └──────┘  
pid  ─────┘       └┘         └┘       └────┘  
st   ───────────────────────────────────────────┘└─
631  end
st   ──┘
632  
633  end
634  
635  lemma coeff_nat_degree_eq_zero_of_degree_lt (h : degree p < degree q) : coeff p (nat_degree q) = 0 :=
id                                                    └────┘   └────┘     └───┘   └────────┘   
src                                                   └────┘    └────┘      └───┘    └────────┘    
typ                                                   └────┘   └────┘     └───┘   └────────┘   
doc                                                   └────┘     └────┘      └───┘    └────────┘
636  coeff_eq_zero_of_degree_lt (lt_of_lt_of_le h degree_le_nat_degree)
id   └────────────────────────┘  └────────────┘  └──────────────────┘
src  └────────────────────────┘  └────────────┘   └──────────────────┘
typ  └────────────────────────┘  └────────────┘  └──────────────────┘
637  
638  lemma ne_zero_of_degree_gt {n : with_bot ℕ} (h : n < degree p) : p ≠ 0 :=
id                                   └──────┘          └────┘      
src                                  └──────┘           └────┘        
typ                                  └──────┘          └────┘      
doc                                                       └────┘
639  mt degree_eq_bot.2 (ne.symm (ne_of_lt (lt_of_le_of_lt bot_le h)))
id   └┘ └───────────┘   └─────┘  └──────┘  └────────────┘ └────┘ 
src  └┘ └───────────┘   └─────┘  └──────┘  └────────────┘ └────┘
typ  └┘ └───────────┘   └─────┘  └──────┘  └────────────┘ └────┘ 
640  
641  lemma eq_C_of_degree_le_zero (h : degree p ≤ 0) : p = C (coeff p 0) :=
id                                     └────┘            └───┘ 
src                                    └────┘              └───┘
typ                                    └────┘            └───┘ 
doc                                    └────┘                └───┘
642  begin
st   └─────
643    refine ext (λ n, _),
id            └─┘
src    └─────┘└─┘  └────┘
typ    └─────┘└─┘  └────┘
doc    └─────┘     └────┘
txt    └─────┘     └────┘
par    └─────┘     └────┘
pid               └────┘
st   ────────────────────┘└─
644    cases n,
id           
src    └────┘
typ    └────┘
doc    └────┘
txt    └────┘
par    └────┘
pid         
st   ────────┘└─
645    { simp },
src      └───┘
typ      └───┘
doc      └───┘
txt      └───┘
par      └───┘
pid          
st   ───┘└───┘└┘
646    { have : degree p < ↑(nat.succ n) := lt_of_le_of_lt h (with_bot.some_lt_some.2 (nat.succ_pos _)),
id              └────┘    └──────┘      └────────────┘   └───────────────────┘    └──────────┘
src      └─────┘└────┘  └──────┘ └───┘└────────────┘  └───────────────────┘└─┘ └──────────┘└──┘
typ      └─────┘└────┘ └──────┘└───┘└────────────┘ └───────────────────┘└─┘ └──────────┘└──┘
doc      └─────┘└────┘             └───┘                                     └─┘             └──┘
txt      └─────┘                   └───┘                                     └─┘             └──┘
par      └─────┘                   └───┘                                     └─┘             └──┘
pid      └───┘└┘                   └──┘                                     └─┘             └──┘
st   ─────────────────────────────────────────────────────────────────────────────────────────────────┘└─
647      rw [coeff_C, if_neg (nat.succ_ne_zero _), coeff_eq_zero_of_degree_lt this] }
id           └─────┘  └────┘  └──────────────┘     └────────────────────────┘ └──┘
src      └──┘└─────┘└┘└────┘ └──────────────┘└───┘└────────────────────────┘    └┘
typ      └──┘└─────┘└┘└────┘ └──────────────┘└───┘└────────────────────────┘└──┘└┘
doc      └──┘       └┘                       └───┘                              └┘
txt      └──┘       └┘                       └───┘                              └┘
par      └──┘       └┘                       └───┘                              └┘
pid        └┘       └┘                       └───┘                              
st   ──────────────┘└───────────────────────────┘└───────────────────────────────┘└─
648  end
st   ──┘
649  
650  lemma eq_C_of_degree_eq_zero (h : degree p = 0) : p = C (coeff p 0) :=
id                                     └────┘            └───┘ 
src                                    └────┘              └───┘
typ                                    └────┘            └───┘ 
doc                                    └────┘                └───┘
651  eq_C_of_degree_le_zero (h ▸ le_refl _)
id   └────────────────────┘    └─────┘
src  └────────────────────┘     └─────┘
typ  └────────────────────┘    └─────┘
652  
653  lemma degree_le_zero_iff : degree p ≤ 0 ↔ p = C (coeff p 0) :=
id                              └────┘          └───┘ 
src                             └────┘            └───┘
typ                             └────┘          └───┘ 
doc                             └────┘               └───┘
654  ⟨eq_C_of_degree_le_zero, λ h, h.symm ▸ degree_C_le⟩
id    └────────────────────┘      └───┘  └─────────┘
src   └────────────────────┘        └───┘  └─────────┘
typ   └────────────────────┘      └───┘  └─────────┘
655  
656  lemma degree_add_le (p q : polynomial α) : degree (p + q) ≤ max (degree p) (degree q) :=
id                              └────────┘     └────┘       └─┘  └────┘    └────┘ 
src                             └────────┘      └────┘         └─┘  └────┘     └────┘
typ                             └────────┘     └────┘       └─┘  └────┘    └────┘ 
doc                             └────────┘      └────┘                └────┘     └────┘
657  calc degree (p + q) = ((p + q).support).sup some : rfl
id        └────┘             └─────┘  └─┘  └──┘   └─┘
src       └────┘                 └─────┘  └─┘  └──┘   └─┘
typ       └────┘             └─────┘  └─┘  └──┘   └─┘
doc       └────┘                            └─┘
658    ... ≤ (p.support ∪ q.support).sup some : by convert sup_mono support_add
id            └──────┘  └──────┘ └─┘  └──┘              └──────┘ └─────────┘
src            └──────┘   └──────┘ └─┘  └──┘      └──────┘└──────┘└─────────┘
typ           └──────┘  └──────┘ └─┘  └──┘      └──────┘└──────┘└─────────┘
doc                                 └─┘            └──────┘                   
txt                                                └──────┘                   
par                                                └──────┘                   
pid                                                                          
st                                                └─────────────────────────────
659    ... = p.support.sup some ⊔ q.support.sup some : by convert sup_union
id           └──────┘└──┘ └──┘  └──────┘└──┘ └──┘              └───────┘
src  ─┘       └──────┘└──┘ └──┘   └──────┘└──┘ └──┘      └──────┘└───────┘
typ  ─┘      └──────┘└──┘ └──┘  └──────┘└──┘ └──┘      └──────┘└───────┘
doc  ─┘               └──┘                 └──┘           └──────┘         
txt  ─┘                                                   └──────┘         
par  ─┘                                                   └──────┘         
pid  ─┘                                                                   
st   ─┘                                                  └──────────────────
660    ... = _ : with_bot.sup_eq_max _ _
id               └─────────────────┘
src  ─┘          └─────────────────┘
typ  ─┘          └─────────────────┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘
661  
662  @[simp] lemma leading_coeff_zero : leading_coeff (0 : polynomial α) = 0 := rfl
id                                      └───────────┘      └────────┘         └─┘
src                                     └───────────┘      └────────┘          └─┘
typ                                     └───────────┘      └────────┘         └─┘
doc    └──┘                             └───────────┘      └────────┘
663  
664  @[simp] lemma leading_coeff_eq_zero : leading_coeff p = 0 ↔ p = 0 :=
id                                         └───────────┘       
src                                        └───────────┘         
typ                                        └───────────┘       
doc    └──┘                                └───────────┘
665  ⟨λ h, by_contradiction $ λ hp, mt mem_support_iff.1
id        └──────────────┘     └┘  └┘ └─────────────┘
src        └──────────────┘         └┘ └─────────────┘
typ       └──────────────┘     └┘  └┘ └─────────────┘
666    (not_not.2 h) (mem_of_max (degree_eq_nat_degree hp)),
id      └─────┘     └────────┘  └──────────────────┘ └┘
src     └─────┘      └────────┘  └──────────────────┘
typ     └─────┘     └────────┘  └──────────────────┘ └┘
667  λ h, h.symm ▸ leading_coeff_zero⟩
id       └───┘  └────────────────┘
src        └───┘  └────────────────┘
typ      └───┘  └────────────────┘
668  
669  lemma leading_coeff_eq_zero_iff_deg_eq_bot : leading_coeff p = 0 ↔ degree p = ⊥ :=
id                                                └───────────┘      └────┘   
src                                               └───────────┘       └────┘    
typ                                               └───────────┘      └────┘   
doc                                               └───────────┘         └────┘
670  by rw [leading_coeff_eq_zero, degree_eq_bot]
id          └───────────────────┘  └───────────┘
src     └──┘└───────────────────┘└┘└───────────┘└─
typ     └──┘└───────────────────┘└┘└───────────┘└─
doc     └──┘                     └┘             └─
txt     └──┘                     └┘             └─
par     └──┘                     └┘             └─
pid       └┘                     └┘             
st     └────────────────────────┘└─────────────┘
671  
src  
typ  
doc  
txt  
par  
pid  
st   
672  lemma degree_add_eq_of_degree_lt (h : degree p < degree q) : degree (p + q) = degree q :=
id                                         └────┘   └────┘     └────┘       └────┘ 
src                                        └────┘    └────┘      └────┘         └────┘
typ                                        └────┘   └────┘     └────┘       └────┘ 
doc                                        └────┘     └────┘      └────┘           └────┘
673  le_antisymm (max_eq_right_of_lt h ▸ degree_add_le _ _) $ degree_le_degree $
id   └─────────┘  └────────────────┘   └───────────┘        └──────────────┘
src  └─────────┘  └────────────────┘    └───────────┘        └──────────────┘
typ  └─────────┘  └────────────────┘   └───────────┘        └──────────────┘
674    begin
st     └─────
675      rw [coeff_add, coeff_nat_degree_eq_zero_of_degree_lt h, zero_add],
id           └───────┘  └───────────────────────────────────┘   └──────┘
src      └──┘└───────┘└┘└───────────────────────────────────┘ └┘└──────┘
typ      └──┘└───────┘└┘└───────────────────────────────────┘└┘└──────┘
doc      └──┘         └┘                                      └┘        
txt      └──┘         └┘                                      └┘        
par      └──┘         └┘                                      └┘        
pid        └┘         └┘                                      └┘        
st   ────────────────┘└───────────────────────────────────────┘└────────┘└──
676      exact mt leading_coeff_eq_zero.1 (ne_zero_of_degree_gt h)
id             └┘ └───────────────────┘    └──────────────────┘ 
src      └────┘└┘└───────────────────┘└─┘ └──────────────────┘ └─
typ      └────┘└┘└───────────────────┘└─┘ └──────────────────┘└─
doc      └────┘                       └─┘                      └─
txt      └────┘                       └─┘                      └─
par      └────┘                       └─┘                      └─
pid                                  └─┘                      
st   ──────────────────────────────────────────────────────────────
677    end
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘└─┘
678  
679  lemma degree_add_C (hp : 0 < degree p) : degree (p + C a) = degree p :=
id                               └────┘     └────┘        └────┘ 
src                              └────┘      └────┘          └────┘
typ                              └────┘     └────┘        └────┘ 
doc                               └────┘      └────┘            └────┘
680  add_comm (C a) p ▸ degree_add_eq_of_degree_lt $ lt_of_le_of_lt degree_C_le hp
id   └──────┘       └────────────────────────┘   └────────────┘ └─────────┘ └┘
src  └──────┘         └────────────────────────┘   └────────────┘ └─────────┘
typ  └──────┘       └────────────────────────┘   └────────────┘ └─────────┘ └┘
doc            
681  
682  lemma degree_add_eq_of_leading_coeff_add_ne_zero (h : leading_coeff p + leading_coeff q ≠ 0) :
id                                                         └───────────┘   └───────────┘  
src                                                        └───────────┘    └───────────┘   
typ                                                        └───────────┘   └───────────┘  
doc                                                        └───────────┘     └───────────┘
683    degree (p + q) = max p.degree q.degree :=
id     └────┘       └─┘ └─────┘ └─────┘
src    └────┘         └─┘  └─────┘  └─────┘
typ    └────┘       └─┘ └─────┘ └─────┘
doc    └────┘                └─────┘  └─────┘
684  le_antisymm (degree_add_le _ _) $
id   └─────────┘  └───────────┘
src  └─────────┘  └───────────┘
typ  └─────────┘  └───────────┘
685    match lt_trichotomy (degree p) (degree q) with
id           └───────────┘  └────┘    └────┘ 
src          └───────────┘  └────┘     └────┘
typ          └───────────┘  └────┘    └────┘ 
doc                         └────┘     └────┘
686    | or.inl hlt :=
id       └────┘
src      └────┘
typ      └────┘
687      by rw [degree_add_eq_of_degree_lt hlt, max_eq_right_of_lt hlt]; exact le_refl _
id              └────────────────────────┘ └─┘  └────────────────┘ └─┘         └─────┘
src         └──┘└────────────────────────┘   └┘└────────────────┘     └────┘└─────┘└──
typ         └──┘└────────────────────────┘└─┘└┘└────────────────┘└─┘  └────┘└─────┘└──
doc         └──┘                             └┘                       └────┘       └──
txt         └──┘                             └┘                       └────┘       └──
par         └──┘                             └┘                       └────┘       └──
pid           └┘                             └┘                                   └┘
st         └─────────────────────────────────┘└──────────────────────┘└─────────────────
688    | or.inr (or.inl heq) :=
id       └────┘  └────┘
src  ─┘  └────┘  └────┘
typ  ─┘  └────┘  └────┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘
689      le_of_not_gt $
id       └──────────┘
src      └──────────┘
typ      └──────────┘
690        assume hlt : max (degree p) (degree q) > degree (p + q),
id                      └─┘  └────┘    └────┘    └────┘    
src                     └─┘  └────┘     └────┘     └────┘    
typ                     └─┘  └────┘    └────┘    └────┘    
doc                          └────┘     └────┘      └────┘
691        h $ show leading_coeff p + leading_coeff q = 0,
id                 └───────────┘   └───────────┘  
src                 └───────────┘    └───────────┘   
typ                └───────────┘   └───────────┘  
doc                 └───────────┘     └───────────┘
692        begin
st         └─────
693          rw [heq, max_self] at hlt,
id               └─┘  └──────┘
src          └──┘└─┘└┘└──────┘└──────┘
typ          └──┘└─┘└┘└──────┘└──────┘
doc          └──┘   └┘        └──────┘
txt          └──┘   └┘        └──────┘
par          └──┘   └┘        └──────┘
pid            └┘   └┘        └─────┘
st   ──────────────┘└────────┘└─────┘└─
694          rw [leading_coeff, leading_coeff, nat_degree_eq_of_degree_eq heq, ← coeff_add],
id               └───────────┘  └───────────┘  └────────────────────────┘ └─┘    └───────┘
src          └──┘└───────────┘└┘└───────────┘└┘└────────────────────────┘└─┘└──┘└───────┘
typ          └──┘└───────────┘└┘└───────────┘└┘└────────────────────────┘└─┘└──┘└───────┘
doc          └──┘└───────────┘└┘└───────────┘└┘                             └──┘         
txt          └──┘             └┘             └┘                             └──┘         
par          └──┘             └┘             └┘                             └──┘         
pid            └┘             └┘             └┘                             └──┘         
st   ────────────────────────┘└─────────────┘└──────────────────────────────┘└───────────┘└──
695          exact coeff_nat_degree_eq_zero_of_degree_lt hlt
id                 └───────────────────────────────────┘ └─┘
src          └────┘└───────────────────────────────────┘   
typ          └────┘└───────────────────────────────────┘└─┘
doc          └────┘                                        
txt          └────┘                                        
par          └────┘                                        
pid                                                       
st   ────────────────────────────────────────────────────────
696        end
src  ─────┘
typ  ─────┘
doc  ─────┘
txt  ─────┘
par  ─────┘
pid  ─────┘
st   ─────┘└─┘
697    | or.inr (or.inr hlt) :=
id               └────┘
src              └────┘
typ              └────┘
698      by rw [add_comm, degree_add_eq_of_degree_lt hlt, max_eq_left_of_lt hlt]; exact le_refl _
id              └──────┘  └────────────────────────┘ └─┘  └───────────────┘ └─┘         └─────┘
src         └──┘└──────┘└┘└────────────────────────┘   └┘└───────────────┘     └────┘└─────┘└──
typ         └──┘└──────┘└┘└────────────────────────┘└─┘└┘└───────────────┘└─┘  └────┘└─────┘└──
doc         └──┘        └┘                             └┘                      └────┘       └──
txt         └──┘        └┘                             └┘                      └────┘       └──
par         └──┘        └┘                             └┘                      └────┘       └──
pid           └┘        └┘                             └┘                                  └┘
st         └───────────┘└──────────────────────────────┘└─────────────────────┘└─────────────────
699    end
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘
700  
701  lemma degree_erase_le (p : polynomial α) (n : ℕ) : degree (p.erase n) ≤ degree p :=
id                              └────────┘            └────┘  └────┘    └────┘ 
src                             └────────┘             └────┘   └────┘     └────┘
typ                             └────────┘            └────┘  └────┘    └────┘ 
doc                             └────────┘              └────┘               └────┘
702  by convert sup_mono (erase_subset _ _)
id              └──────┘  └──────────┘
src     └──────┘└──────┘ └──────────┘└─────
typ     └──────┘└──────┘ └──────────┘└─────
doc     └──────┘                     └─────
txt     └──────┘                     └─────
par     └──────┘                     └─────
pid                                 └───┘
st     └────────────────────────────────────
703  
src  
typ  
doc  
txt  
par  
pid  
st   
704  lemma degree_erase_lt (hp : p ≠ 0) : degree (p.erase (nat_degree p)) < degree p :=
id                                      └────┘  └────┘  └────────┘     └────┘ 
src                                      └────┘   └────┘  └────────┘      └────┘
typ                                     └────┘  └────┘  └────────┘     └────┘ 
doc                                       └────┘           └────────┘       └────┘
705  lt_of_le_of_ne (degree_erase_le _ _) $
id   └────────────┘  └─────────────┘
src  └────────────┘  └─────────────┘
typ  └────────────┘  └─────────────┘
706    (degree_eq_nat_degree hp).symm ▸ (by convert λ h, not_mem_erase _ _ (mem_of_max h))
id      └──────────────────┘ └┘ └──┘                    └───────────┘      └────────┘
src     └──────────────────┘    └──┘       └──────┘ └──┘└───────────┘└───┘ └────────┘ 
typ     └──────────────────┘ └┘ └──┘       └──────┘ └──┘└───────────┘└───┘ └────────┘ 
doc                                         └──────┘ └──┘             └───┘            
txt                                         └──────┘ └──┘             └───┘            
par                                         └──────┘ └──┘             └───┘            
pid                                                 └──┘             └───┘            
st                                         └────────────────────────────────────────────┘
707  
708  lemma degree_sum_le (s : finset β) (f : β → polynomial α) :
id                            └────┘           └────────┘ 
src                           └────┘             └────────┘
typ                           └────┘           └────────┘ 
doc                           └────┘             └────────┘
709    degree (s.sum f) ≤ s.sup (λ b, degree (f b)) :=
id     └────┘  └──┘    └──┘      └────┘   
src    └────┘   └──┘      └──┘       └────┘
typ    └────┘  └──┘    └──┘      └────┘   
doc    └────┘              └──┘       └────┘
710  finset.induction_on s (by simp only [sum_empty, sup_empty, degree_zero, le_refl]) $
id   └─────────────────┘                 └───────┘  └───────┘  └─────────┘  └─────┘
src  └─────────────────┘       └─────────┘└───────┘└┘└───────┘└┘└─────────┘└┘└─────┘
typ  └─────────────────┘      └─────────┘└───────┘└┘└───────┘└┘└─────────┘└┘└─────┘
doc  └─────────────────┘       └─────────┘         └┘         └┘           └┘       
txt                            └─────────┘         └┘         └┘           └┘       
par                            └─────────┘         └┘         └┘           └┘       
pid                                └──┘└┘         └┘         └┘           └┘       
st                            └─────────────────────────────────────────────────────┘
711    assume a s has ih,
id              └─┘ └┘
typ             └─┘ └┘
712    calc degree (sum (insert a s) f) ≤ max (degree (f a)) (degree (s.sum f)) :
id          └────┘  └─┘  └────┘        └─┘  └────┘       └────┘  └──┘ 
src         └────┘  └─┘  └────┘           └─┘  └────┘         └────┘   └──┘
typ         └────┘  └─┘  └────┘        └─┘  └────┘       └────┘  └──┘ 
doc         └────┘                             └────┘         └────┘
713      by rw sum_insert has; exact degree_add_le _ _
id             └────────┘ └─┘        └───────────┘
src         └─┘└────────┘     └────┘└───────────┘└────
typ         └─┘└────────┘└─┘  └────┘└───────────┘└────
doc         └─┘               └────┘             └────
txt         └─┘               └────┘             └────
par         └─┘               └────┘             └────
pid                                            └──┘
st         └───────────────────────────────────────────
714    ... ≤ _ : by rw [sup_insert, with_bot.sup_eq_max]; exact max_le_max (le_refl _) ih
id                      └────────┘  └─────────────────┘         └────────┘  └─────┘    └┘
src  ─┘             └──┘└────────┘└┘└─────────────────┘  └────┘└────────┘ └─────┘└──┘  
typ  ─┘             └──┘└────────┘└┘└─────────────────┘  └────┘└────────┘ └─────┘└──┘└┘
doc  ─┘             └──┘          └┘                     └────┘                  └──┘  
txt  ─┘             └──┘          └┘                     └────┘                  └──┘  
par  ─┘             └──┘          └┘                     └────┘                  └──┘  
pid  ─┘               └┘          └┘                                            └──┘  
st   ─┘            └─────────────┘└───────────────────┘└─────────────────────────────────
715  
src  
typ  
doc  
txt  
par  
pid  
st   
716  lemma degree_mul_le (p q : polynomial α) : degree (p * q) ≤ degree p + degree q :=
id                              └────────┘     └────┘       └────┘   └────┘ 
src                             └────────┘      └────┘         └────┘    └────┘
typ                             └────────┘     └────┘       └────┘   └────┘ 
doc                             └────────┘      └────┘           └────┘     └────┘
717  calc degree (p * q) ≤ (p.support).sup (λi, degree (sum q (λj a, C (coeff p i * a) * X ^ (i + j)))) :
id        └────┘         └──────┘ └─┘      └────┘  └─┘         └───┘            
src       └────┘            └──────┘ └─┘       └────┘  └─┘            └───┘               
typ       └────┘         └──────┘ └─┘      └────┘  └─┘         └───┘            
doc       └────┘                      └─┘       └────┘  └─┘            └───┘            
718      by simp only [single_eq_C_mul_X.symm]; exact degree_sum_le _ _
id                                                    └───────────┘
src         └─────────┘                        └────┘└───────────┘└────
typ         └─────────┘└────────────────────┘  └────┘└───────────┘└────
doc         └─────────┘                        └────┘             └────
txt         └─────────┘                        └────┘             └────
par         └─────────┘                        └────┘             └────
pid             └──┘└┘                                          └──┘
st         └────────────────────────────────────────────────────────────
719    ... ≤ p.support.sup (λi, q.support.sup (λj, degree (C (coeff p i * coeff q j) * X ^ (i + j)))) :
id           └──────┘└──┘     └──────┘└──┘     └────┘    └───┘    └───┘          
src  ─┘       └──────┘└──┘       └──────┘└──┘      └────┘    └───┘      └───┘            
typ  ─┘      └──────┘└──┘     └──────┘└──┘     └────┘    └───┘    └───┘          
doc  ─┘               └──┘               └──┘      └────┘    └───┘       └───┘        
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘
720      finset.sup_mono_fun (assume i hi,  degree_sum_le _ _)
id       └─────────────────┘          └┘   └───────────┘
src      └─────────────────┘                └───────────┘
typ      └─────────────────┘          └┘   └───────────┘
721    ... ≤ degree p + degree q :
id           └────┘   └────┘ 
src          └────┘    └────┘
typ          └────┘   └────┘ 
doc          └────┘     └────┘
722      begin
st       └─────
723        refine finset.sup_le (λ a ha, finset.sup_le (λ b hb, le_trans (degree_monomial_le _ _) _)),
id                                       └───────────┘          └──────┘  └────────────────┘
src        └─────┘               └─────┘└───────────┘  └─────┘└──────┘ └────────────────┘└───────┘
typ        └─────┘               └─────┘└───────────┘  └─────┘└──────┘ └────────────────┘└───────┘
doc        └─────┘               └─────┘               └─────┘                           └───────┘
txt        └─────┘               └─────┘               └─────┘                           └───────┘
par        └─────┘               └─────┘               └─────┘                           └───────┘
pid                             └─────┘               └─────┘                           └───────┘
st   ───────────────────────────────────────────────────────────────────────────────────────────────┘└─
724        rw [with_bot.coe_add],
id             └──────────────┘
src        └──┘└──────────────┘
typ        └──┘└──────────────┘
doc        └──┘                
txt        └──┘                
par        └──┘                
pid          └┘                
st   ─────────────────────────┘└──
725        rw mem_support_iff at ha hb,
id            └─────────────┘
src        └─┘└─────────────┘└───────┘
typ        └─┘└─────────────┘└───────┘
doc        └─┘               └───────┘
txt        └─┘               └───────┘
par        └─┘               └───────┘
pid                         └───────┘
st   ────────────────────────────────┘└─
726        exact add_le_add' (le_degree_of_ne_zero ha) (le_degree_of_ne_zero hb)
id               └─────────┘                       └┘   └──────────────────┘ └┘
src        └────┘└─────────┘                       └┘ └──────────────────┘  └─
typ        └────┘└─────────┘                     └┘└┘ └──────────────────┘└┘└─
doc        └────┘                                  └┘                       └─
txt        └────┘                                  └┘                       └─
par        └────┘                                  └┘                       └─
pid                                               └┘                       
st   ────────────────────────────────────────────────────────────────────────────
727      end
src  ───┘
typ  ───┘
doc  ───┘
txt  ───┘
par  ───┘
pid  ───┘
st   ───┘└─┘
728  
729  lemma degree_pow_le (p : polynomial α) : ∀ n, degree (p ^ n) ≤ add_monoid.smul n (degree p)
id                            └────────┘         └────┘       └─────────────┘   └────┘ 
src                           └────────┘           └────┘         └─────────────┘    └────┘
typ                           └────────┘         └────┘       └─────────────┘   └────┘ 
doc                           └────────┘           └────┘                              └────┘
730  | 0     := by rw [pow_zero, add_monoid.zero_smul]; exact degree_one_le
id                     └──────┘  └──────────────────┘         └───────────┘
src                └──┘└──────┘└┘└──────────────────┘  └────┘└───────────┘
typ                └──┘└──────┘└┘└──────────────────┘  └────┘└───────────┘
doc                └──┘        └┘                      └────┘             
txt                └──┘        └┘                      └────┘             
par                └──┘        └┘                      └────┘             
pid                  └┘        └┘                                        
st                └───────────┘└────────────────────┘└────────────────────┘
731  | (n+1) := calc degree (p ^ (n + 1)) ≤ degree p + degree (p ^ n) :
id                 └────┘              └────┘   └────┘   
src                 └────┘               └────┘    └────┘    
typ                └────┘              └────┘   └────┘   
doc                  └────┘                 └────┘     └────┘
732      by rw pow_succ; exact degree_mul_le _ _
id             └──────┘        └───────────┘
src         └─┘└──────┘  └────┘└───────────┘└────
typ         └─┘└──────┘  └────┘└───────────┘└────
doc         └─┘          └────┘             └────
txt         └─┘          └────┘             └────
par         └─┘          └────┘             └────
pid                                       └──┘
st         └─────────────────────────────────────
733    ... ≤ _ : by rw succ_smul; exact add_le_add' (le_refl _) (degree_pow_le _)
id                     └───────┘        └─────────┘  └─────┘     └───────────┘
src  ─┘             └─┘└───────┘  └────┘└─────────┘ └─────┘└──┘              └───
typ  ─┘             └─┘└───────┘  └────┘└─────────┘ └─────┘└──┘ └───────────┘└───
doc  ─┘             └─┘           └────┘                   └──┘              └───
txt  ─┘             └─┘           └────┘                   └──┘              └───
par  ─┘             └─┘           └────┘                   └──┘              └───
pid  ─┘                                                  └──┘              └─┘
st   ─┘            └──────────────────────────────────────────────────────────────
734  
src  
typ  
doc  
txt  
par  
pid  
st   
735  @[simp] lemma leading_coeff_monomial (a : α) (n : ℕ) : leading_coeff (C a * X ^ n) = a :=
id                                                        └───────────┘          
src                                                        └───────────┘           
typ                                                       └───────────┘          
doc    └──┘                                                 └───────────┘       
736  begin
st   └─────
737    by_cases ha : a = 0,
id                    
src    └───────┘  └─┘ └┘
typ    └───────┘  └─┘└┘
doc    └───────┘  └─┘  └┘
txt    └───────┘  └─┘  └┘
par    └───────┘  └─┘  └┘
pid              └─┘  
st   ────────────────────┘└─
738    { simp only [ha, C_0, zero_mul, leading_coeff_zero] },
id                  └┘  └─┘  └──────┘  └────────────────┘
src      └─────────┘  └┘└─┘└┘└──────┘└┘└────────────────┘└┘
typ      └─────────┘└┘└┘└─┘└┘└──────┘└┘└────────────────┘└┘
doc      └─────────┘  └┘   └┘        └┘                  └┘
txt      └─────────┘  └┘   └┘        └┘                  └┘
par      └─────────┘  └┘   └┘        └┘                  └┘
pid          └──┘└┘  └┘   └┘        └┘                  
st   ───┘└────────────────────────────────────────────────┘└┘
739    { rw [leading_coeff, nat_degree, degree_monomial _ ha, ← single_eq_C_mul_X],
id           └───────────┘  └────────┘  └─────────────┘   └┘    └───────────────┘
src      └──┘└───────────┘└┘└────────┘└┘└─────────────┘└─┘  └──┘└───────────────┘
typ      └──┘└───────────┘└┘└────────┘└┘└─────────────┘└─┘└┘└──┘└───────────────┘
doc      └──┘└───────────┘└┘└────────┘└┘               └─┘  └──┘                 
txt      └──┘             └┘          └┘               └─┘  └──┘                 
par      └──┘             └┘          └┘               └─┘  └──┘                 
pid        └┘             └┘          └┘               └─┘  └──┘                 
st   ────────────────────┘└──────────┘└────────────────────┘└───────────────────┘└──
740      exact @finsupp.single_eq_same _ _ _ n a }
id              └────────────────────┘        
src      └────┘ └────────────────────┘└─────┘  
typ      └────┘ └────────────────────┘└─────┘
doc      └────┘                       └─────┘  
txt      └────┘                       └─────┘  
par      └────┘                       └─────┘  
pid                                  └─────┘  
st   ───────────────────────────────────────────┘└─
741  end
st   ──┘
742  
743  @[simp] lemma leading_coeff_C (a : α) : leading_coeff (C a) = a :=
id                                          └───────────┘      
src                                          └───────────┘      
typ                                         └───────────┘      
doc    └──┘                                  └───────────┘  
744  suffices leading_coeff (C a * X^0) = a, by rwa [pow_zero, mul_one] at this,
id            └───────────┘                   └──────┘  └─────┘
src           └───────────┘                └───┘└──────┘└┘└─────┘└───────┘
typ           └───────────┘              └───┘└──────┘└┘└─────┘└───────┘
doc           └───────────┘                   └───┘        └┘       └───────┘
txt                                             └───┘        └┘       └───────┘
par                                             └───┘        └┘       └───────┘
pid                                                └┘        └┘       └──────┘
st                                             └────────────┘└───────┘└──────┘
745  leading_coeff_monomial a 0
id   └────────────────────┘ 
src  └────────────────────┘
typ  └────────────────────┘ 
746  
747  @[simp] lemma leading_coeff_X : leading_coeff (X : polynomial α) = 1 :=
id                                   └───────────┘     └────────┘   
src                                  └───────────┘     └────────┘    
typ                                  └───────────┘     └────────┘   
doc    └──┘                          └───────────┘     └────────┘
748  suffices leading_coeff (C (1:α) * X^1) = 1, by rwa [C_1, pow_one, one_mul] at this,
id            └───────────┘                        └─┘  └─────┘  └─────┘
src           └───────────┘                    └───┘└─┘└┘└─────┘└┘└─────┘└───────┘
typ           └───────────┘                   └───┘└─┘└┘└─────┘└┘└─────┘└───────┘
doc           └───────────┘                       └───┘   └┘       └┘       └───────┘
txt                                                 └───┘   └┘       └┘       └───────┘
par                                                 └───┘   └┘       └┘       └───────┘
pid                                                    └┘   └┘       └┘       └──────┘
st                                                 └───────┘└───────┘└───────┘└──────┘
749  leading_coeff_monomial 1 1
id   └────────────────────┘
src  └────────────────────┘
typ  └────────────────────┘
750  
751  @[simp] lemma monic_X : monic (X : polynomial α) := leading_coeff_X
id                           └───┘     └────────┘      └─────────────┘
src                          └───┘     └────────┘       └─────────────┘
typ                          └───┘     └────────┘      └─────────────┘
doc    └──┘                  └───┘     └────────┘
752  
753  @[simp] lemma leading_coeff_one : leading_coeff (1 : polynomial α) = 1 :=
id                                     └───────────┘      └────────┘   
src                                    └───────────┘      └────────┘    
typ                                    └───────────┘      └────────┘   
doc    └──┘                            └───────────┘      └────────┘
754  suffices leading_coeff (C (1:α) * X^0) = 1, by rwa [C_1, pow_zero, mul_one] at this,
id            └───────────┘                        └─┘  └──────┘  └─────┘
src           └───────────┘                    └───┘└─┘└┘└──────┘└┘└─────┘└───────┘
typ           └───────────┘                   └───┘└─┘└┘└──────┘└┘└─────┘└───────┘
doc           └───────────┘                       └───┘   └┘        └┘       └───────┘
txt                                                 └───┘   └┘        └┘       └───────┘
par                                                 └───┘   └┘        └┘       └───────┘
pid                                                    └┘   └┘        └┘       └──────┘
st                                                 └───────┘└────────┘└───────┘└──────┘
755  leading_coeff_monomial 1 0
id   └────────────────────┘
src  └────────────────────┘
typ  └────────────────────┘
756  
757  @[simp] lemma monic_one : monic (1 : polynomial α) := leading_coeff_C _
id                             └───┘      └────────┘      └─────────────┘
src                            └───┘      └────────┘       └─────────────┘
typ                            └───┘      └────────┘      └─────────────┘
doc    └──┘                    └───┘      └────────┘
758  
759  lemma monic.ne_zero_of_zero_ne_one (h : (0:α) ≠ 1) {p : polynomial α} (hp : p.monic) :
id                                                         └────────┘         └────┘
src                                                         └────────┘           └────┘
typ                                                        └────────┘         └────┘
doc                                                          └────────┘           └────┘
760    p ≠ 0 :=
id      
src      
typ     
761  by { contrapose! h, rwa [h] at hp }
id                            
src       └───────────┘  └───┘ └──────┘
typ       └───────────┘  └───┘└──────┘
doc       └───────────┘  └───┘ └──────┘
txt       └───────────┘  └───┘ └──────┘
par       └───────────┘  └───┘ └──────┘
pid                 └┘     └┘ └────┘
st     └──────────────┘└──────┘└─────┘└┘
762  
763  lemma monic.ne_zero {α : Type*} [nonzero_comm_ring α] {p : polynomial α} (hp : p.monic) :
id                                    └───────────────┘        └────────┘         └────┘
src                                   └───────────────┘         └────────┘           └────┘
typ                                   └───────────────┘        └────────┘         └────┘
doc                                   └───────────────┘         └────────┘           └────┘
764    p ≠ 0 :=
id      
src      
typ     
765  hp.ne_zero_of_zero_ne_one $ zero_ne_one
id   └┘└─────────────────────┘   └─────────┘
src    └─────────────────────┘   └─────────┘
typ  └┘└─────────────────────┘   └─────────┘
766  
767  lemma leading_coeff_add_of_degree_lt (h : degree p < degree q) :
id                                             └────┘   └────┘ 
src                                            └────┘    └────┘
typ                                            └────┘   └────┘ 
doc                                            └────┘     └────┘
768    leading_coeff (p + q) = leading_coeff q :=
id     └───────────┘       └───────────┘ 
src    └───────────┘         └───────────┘
typ    └───────────┘       └───────────┘ 
doc    └───────────┘           └───────────┘
769  have coeff p (nat_degree q) = 0, from coeff_nat_degree_eq_zero_of_degree_lt h,
id        └───┘   └────────┘            └───────────────────────────────────┘ 
src       └───┘    └────────┘             └───────────────────────────────────┘
typ       └───┘   └────────┘            └───────────────────────────────────┘ 
doc       └───┘    └────────┘
770  by simp only [leading_coeff, nat_degree_eq_of_degree_eq (degree_add_eq_of_degree_lt h),
id                 └───────────┘  └────────────────────────┘  └────────────────────────┘ 
src     └─────────┘└───────────┘└┘└────────────────────────┘ └────────────────────────┘ └──
typ     └─────────┘└───────────┘└┘└────────────────────────┘ └────────────────────────┘└──
doc     └─────────┘└───────────┘└┘                                                      └──
txt     └─────────┘             └┘                                                      └──
par     └─────────┘             └┘                                                      └──
pid         └──┘└┘             └┘                                                      └──
st     └─────────────────────────────────────────────────────────────────────────────────────
771    this, coeff_add, zero_add]
id     └──┘  └───────┘  └──────┘
src  ─┘    └┘└───────┘└┘└──────┘└─
typ  ─┘└──┘└┘└───────┘└┘└──────┘└─
doc  ─┘    └┘         └┘        └─
txt  ─┘    └┘         └┘        └─
par  ─┘    └┘         └┘        └─
pid  ─┘    └┘         └┘        
st   ─────────────────────────────
772  
src  
typ  
doc  
txt  
par  
pid  
st   
773  lemma leading_coeff_add_of_degree_eq (h : degree p = degree q)
id                                             └────┘   └────┘ 
src                                            └────┘    └────┘
typ                                            └────┘   └────┘ 
doc                                            └────┘     └────┘
774    (hlc : leading_coeff p + leading_coeff q ≠ 0) :
id            └───────────┘   └───────────┘  
src           └───────────┘    └───────────┘   
typ           └───────────┘   └───────────┘  
doc           └───────────┘     └───────────┘
775    leading_coeff (p + q) = leading_coeff p + leading_coeff q :=
id     └───────────┘       └───────────┘   └───────────┘ 
src    └───────────┘         └───────────┘    └───────────┘
typ    └───────────┘       └───────────┘   └───────────┘ 
doc    └───────────┘           └───────────┘     └───────────┘
776  have nat_degree (p + q) = nat_degree p,
id        └────────┘       └────────┘ 
src       └────────┘         └────────┘
typ       └────────┘       └────────┘ 
doc       └────────┘           └────────┘
777    by apply nat_degree_eq_of_degree_eq; rw [degree_add_eq_of_leading_coeff_add_ne_zero hlc, h, max_self],
id              └────────────────────────┘      └────────────────────────────────────────┘ └─┘    └──────┘
src       └────┘└────────────────────────┘  └──┘└────────────────────────────────────────┘   └┘ └┘└──────┘
typ       └────┘└────────────────────────┘  └──┘└────────────────────────────────────────┘└─┘└┘└┘└──────┘
doc       └────┘                            └──┘                                             └┘ └┘        
txt       └────┘                            └──┘                                             └┘ └┘        
par       └────┘                            └──┘                                             └┘ └┘        
pid                                          └┘                                             └┘ └┘        
st       └─────────────────────────────────────┘└────────────────────────────────────────────┘└─┘└────────┘
778  by simp only [leading_coeff, this, nat_degree_eq_of_degree_eq h, coeff_add]
id                 └───────────┘  └──┘  └────────────────────────┘   └───────┘
src     └─────────┘└───────────┘└┘    └┘└────────────────────────┘ └┘└───────┘└─
typ     └─────────┘└───────────┘└┘└──┘└┘└────────────────────────┘└┘└───────┘└─
doc     └─────────┘└───────────┘└┘    └┘                           └┘         └─
txt     └─────────┘             └┘    └┘                           └┘         └─
par     └─────────┘             └┘    └┘                           └┘         └─
pid         └──┘└┘             └┘    └┘                           └┘         
st     └─────────────────────────────────────────────────────────────────────────
779  
src  
typ  
doc  
txt  
par  
pid  
st   
780  @[simp] lemma coeff_mul_degree_add_degree (p q : polynomial α) :
id                                                    └────────┘ 
src                                                   └────────┘
typ                                                   └────────┘ 
doc    └──┘                                           └────────┘
781    coeff (p * q) (nat_degree p + nat_degree q) = leading_coeff p * leading_coeff q :=
id     └───┘       └────────┘   └────────┘    └───────────┘   └───────────┘ 
src    └───┘         └────────┘    └────────┘     └───────────┘    └───────────┘
typ    └───┘       └────────┘   └────────┘    └───────────┘   └───────────┘ 
doc    └───┘          └────────┘     └────────┘      └───────────┘     └───────────┘
782  calc coeff (p * q) (nat_degree p + nat_degree q) =
id        └───┘       └────────┘   └────────┘ 
src       └───┘         └────────┘    └────────┘
typ       └───┘       └────────┘   └────────┘ 
doc       └───┘          └────────┘     └────────┘
783      (nat.antidiagonal (nat_degree p + nat_degree q)).sum
id        └──────────────┘  └────────┘   └────────┘   └─┘
src       └──────────────┘  └────────┘    └────────┘    └─┘
typ       └──────────────┘  └────────┘   └────────┘   └─┘
doc       └──────────────┘  └────────┘     └────────┘
784      (λ x, coeff p x.1 * coeff q x.2) : coeff_mul _ _ _
id            └───┘     └───┘       └───────┘
src            └───┘       └───┘         └───────┘
typ           └───┘     └───┘       └───────┘
doc            └───┘         └───┘
785  ... = coeff p (nat_degree p) * coeff q (nat_degree q) :
id         └───┘   └────────┘    └───┘   └────────┘ 
src        └───┘    └────────┘     └───┘    └────────┘
typ        └───┘   └────────┘    └───┘   └────────┘ 
doc        └───┘    └────────┘      └───┘    └────────┘
786    begin
st     └─────
787      refine finset.sum_eq_single (nat_degree p, nat_degree q) _ _,
id              └──────────────────┘               └────────┘ 
src      └─────┘└──────────────────┘            └┘└────────┘ └───┘
typ      └─────┘└──────────────────┘           └┘└────────┘└───┘
doc      └─────┘                                └┘└────────┘ └───┘
txt      └─────┘                                └┘           └───┘
par      └─────┘                                └┘           └───┘
pid                                            └┘           └───┘
st   ───────────────────────────────────────────────────────────────┘└─
788      { rintro ⟨i,j⟩ h₁ h₂, rw nat.mem_antidiagonal at h₁,
id                                └──────────────────┘
src        └────────────────┘  └─┘└──────────────────┘└────┘
typ        └────────────────┘  └─┘└──────────────────┘└────┘
doc        └────────────────┘  └─┘└──────────────────┘└────┘
txt        └────────────────┘  └─┘                    └────┘
par        └────────────────┘  └─┘                    └────┘
pid              └──────────┘                        └────┘
st   ─────┘└────────────────┘└─────────────────────────────┘└─
789        by_cases H : nat_degree p < i,
id                      └────────┘   
src        └───────┘ └─┘└────────┘ 
typ        └───────┘ └─┘└────────┘
doc        └───────┘ └─┘└────────┘  
txt        └───────┘ └─┘            
par        └───────┘ └─┘            
pid                 └─┘            
st   ──────────────────────────────────┘└─
790        { rw [coeff_eq_zero_of_degree_lt
id               └────────────────────────┘
src          └──┘└────────────────────────┘
typ          └──┘└────────────────────────┘
doc          └──┘                          
txt          └──┘                          
par          └──┘                          
pid            └┘                          
st   ───────┘└──────────────────────────────
791            (lt_of_le_of_lt degree_le_nat_degree (with_bot.coe_lt_coe.2 H)), zero_mul] },
id              └────────────┘ └──────────────────┘  └─────────────────┘       └──────┘
src  ─────────┘ └────────────┘└──────────────────┘ └─────────────────┘└─┘ └──┘└──────┘└┘
typ  ─────────┘ └────────────┘└──────────────────┘ └─────────────────┘└─┘└──┘└──────┘└┘
doc  ─────────┘                                                       └─┘ └──┘        └┘
txt  ─────────┘                                                       └─┘ └──┘        └┘
par  ─────────┘                                                       └─┘ └──┘        └┘
pid  ─────────┘                                                       └─┘ └──┘        
st   ────────────────────────────────────────────────────────────────────────┘└────────┘└┘
792        { rw not_lt_iff_eq_or_lt at H, cases H,
id              └─────────────────┘             
src          └─┘└─────────────────┘└───┘  └────┘
typ          └─┘└─────────────────┘└───┘  └────┘
doc          └─┘                   └───┘  └────┘
txt          └─┘                   └───┘  └────┘
par          └─┘                   └───┘  └────┘
pid                               └───┘       
st   ──────────────────────────────────┘└───────┘└─
793          { subst H, rw add_left_cancel_iff at h₁, dsimp at h₁, subst h₁, exfalso, exact h₂ rfl },
id                        └─────────────────┘                           └┘                 └┘ └─┘
src            └────┘   └─┘└─────────────────┘└────┘  └─────────┘  └────┘    └─────┘  └────┘  └─┘
typ            └────┘  └─┘└─────────────────┘└────┘  └─────────┘  └────┘└┘  └─────┘  └────┘└┘└─┘
doc            └────┘   └─┘                   └────┘  └─────────┘  └────┘    └─────┘  └────┘     
txt            └────┘   └─┘                   └────┘  └─────────┘  └────┘    └─────┘  └────┘     
par            └────┘   └─┘                   └────┘  └─────────┘  └────┘    └─────┘  └────┘     
pid                                         └────┘       └───┘                              
st   ─────────┘└─────┘└────────────────────────────┘└───────────┘└────────┘└───────┘└─────────────┘└┘
794          { suffices : nat_degree q < j,
id                        └────────┘    
src            └─────────┘└────────┘  
typ            └─────────┘└────────┘ 
doc            └─────────┘└────────┘  
txt            └─────────┘            
par            └─────────┘            
pid            └───────┘└┘            
st   ────────────────────────────────────┘└─
795            { rw [coeff_eq_zero_of_degree_lt
id                   └────────────────────────┘
src              └──┘└────────────────────────┘
typ              └──┘└────────────────────────┘
doc              └──┘                          
txt              └──┘                          
par              └──┘                          
pid                └┘                          
st   ───────────┘└──────────────────────────────
796                (lt_of_le_of_lt degree_le_nat_degree (with_bot.coe_lt_coe.2 this)), mul_zero] },
id                  └────────────┘ └──────────────────┘  └─────────────────┘   └──┘    └──────┘
src  ─────────────┘ └────────────┘└──────────────────┘ └─────────────────┘└─┘    └──┘└──────┘└┘
typ  ─────────────┘ └────────────┘└──────────────────┘ └─────────────────┘└─┘└──┘└──┘└──────┘└┘
doc  ─────────────┘                                                       └─┘    └──┘        └┘
txt  ─────────────┘                                                       └─┘    └──┘        └┘
par  ─────────────┘                                                       └─┘    └──┘        └┘
pid  ─────────────┘                                                       └─┘    └──┘        
st   ───────────────────────────────────────────────────────────────────────────────┘└────────┘└┘
797            { by_contra H', rw not_lt at H',
id                                └────┘
src              └──────────┘  └─┘└────┘└────┘
typ              └──────────┘  └─┘└────┘└────┘
doc              └──────────┘  └─┘      └────┘
txt              └──────────┘  └─┘      └────┘
par              └──────────┘  └─┘      └────┘
pid                       └─┘          └────┘
st   ───────────────────────┘└───────────────┘└─
798              exact ne_of_lt (nat.lt_of_lt_of_le
id                     └──────┘  └────────────────┘
src              └────┘└──────┘ └────────────────┘
typ              └────┘└──────┘ └────────────────┘
doc              └────┘                           
txt              └────┘                           
par              └────┘                           
pid                                              
st   ───────────────────────────────────────────────
799                (nat.add_lt_add_right H j) (nat.add_le_add_left H' _)) h₁ } } } },
id                  └──────────────────┘     └─────────────────┘ └┘     └┘
src  ─────────────┘ └──────────────────┘  └┘ └─────────────────┘  └───┘  
typ  ─────────────┘ └──────────────────┘└┘ └─────────────────┘└┘└───┘└┘
doc  ─────────────┘                       └┘                      └───┘  
txt  ─────────────┘                       └┘                      └───┘  
par  ─────────────┘                       └┘                      └───┘  
pid  ─────────────┘                       └┘                      └───┘  
st   ───────────────────────────────────────────────────────────────────────┘└──────┘
800      { intro H, exfalso, apply H, rw nat.mem_antidiagonal }
id                                       └──────────────────┘
src        └─────┘  └─────┘  └────┘   └─┘└──────────────────┘
typ        └─────┘  └─────┘  └────┘   └─┘└──────────────────┘
doc        └─────┘  └─────┘  └────┘   └─┘└──────────────────┘
txt        └─────┘  └─────┘  └────┘   └─┘                    
par        └─────┘  └─────┘  └────┘   └─┘                    
pid             └┘                                         
st   ────────────┘└───────┘└───────┘└────────────────────────┘└─
801    end
st   ────┘
802  
803  lemma degree_mul_eq' (h : leading_coeff p * leading_coeff q ≠ 0) :
id                             └───────────┘   └───────────┘  
src                            └───────────┘    └───────────┘   
typ                            └───────────┘   └───────────┘  
doc                            └───────────┘     └───────────┘
804    degree (p * q) = degree p + degree q :=
id     └────┘       └────┘   └────┘ 
src    └────┘         └────┘    └────┘
typ    └────┘       └────┘   └────┘ 
doc    └────┘           └────┘     └────┘
805  have hp : p ≠ 0 := by refine mt _ h; exact λ hp, by rw [hp, leading_coeff_zero, zero_mul],
id                              └┘                        └┘  └────────────────┘  └──────┘
src                       └─────┘└┘└─┘   └────┘ └───┘  └──┘  └┘└────────────────┘└┘└──────┘
typ                      └─────┘└┘└─┘  └────┘ └───┘  └──┘└┘└┘└────────────────┘└┘└──────┘
doc                        └─────┘  └─┘   └────┘ └───┘  └──┘  └┘                  └┘        
txt                        └─────┘  └─┘   └────┘ └───┘  └──┘  └┘                  └┘        
par                        └─────┘  └─┘   └────┘ └───┘  └──┘  └┘                  └┘        
pid                                └─┘         └───┘  └───┘  └┘                  └┘        
st                        └────────────────────────────┘└─────┘└──────────────────┘└────────┘
806  have hq : q ≠ 0 := by refine mt _ h; exact λ hq, by rw [hq, leading_coeff_zero, mul_zero],
id                              └┘                        └┘  └────────────────┘  └──────┘
src                       └─────┘└┘└─┘   └────┘ └───┘  └──┘  └┘└────────────────┘└┘└──────┘
typ                      └─────┘└┘└─┘  └────┘ └───┘  └──┘└┘└┘└────────────────┘└┘└──────┘
doc                        └─────┘  └─┘   └────┘ └───┘  └──┘  └┘                  └┘        
txt                        └─────┘  └─┘   └────┘ └───┘  └──┘  └┘                  └┘        
par                        └─────┘  └─┘   └────┘ └───┘  └──┘  └┘                  └┘        
pid                                └─┘         └───┘  └───┘  └┘                  └┘        
st                        └────────────────────────────┘└─────┘└──────────────────┘└────────┘
807  le_antisymm (degree_mul_le _ _)
id   └─────────┘  └───────────┘
src  └─────────┘  └───────────┘
typ  └─────────┘  └───────────┘
808  begin
st   └─────
809    rw [degree_eq_nat_degree hp, degree_eq_nat_degree hq],
id         └──────────────────┘ └┘  └──────────────────┘ └┘
src    └──┘└──────────────────┘  └┘└──────────────────┘  
typ    └──┘└──────────────────┘└┘└┘└──────────────────┘└┘
doc    └──┘                      └┘                      
txt    └──┘                      └┘                      
par    └──┘                      └┘                      
pid      └┘                      └┘                      
st   ────────────────────────────┘└───────────────────────┘└──
810    refine le_degree_of_ne_zero _,
id            └──────────────────┘
src    └─────┘└──────────────────┘└┘
typ    └─────┘└──────────────────┘└┘
doc    └─────┘                    └┘
txt    └─────┘                    └┘
par    └─────┘                    └┘
pid                              └┘
st   ──────────────────────────────┘└─
811    rwa coeff_mul_degree_add_degree
id         └─────────────────────────┘
src    └──┘└─────────────────────────┘
typ    └──┘└─────────────────────────┘
doc    └──┘                           
txt    └──┘                           
par    └──┘                           
pid                                  
st   ─────────────────────────────────┘
812  end
st   └─┘
813  
814  lemma nat_degree_mul_eq' (h : leading_coeff p * leading_coeff q ≠ 0) :
id                                 └───────────┘   └───────────┘  
src                                └───────────┘    └───────────┘   
typ                                └───────────┘   └───────────┘  
doc                                └───────────┘     └───────────┘
815    nat_degree (p * q) = nat_degree p + nat_degree q :=
id     └────────┘       └────────┘   └────────┘ 
src    └────────┘         └────────┘    └────────┘
typ    └────────┘       └────────┘   └────────┘ 
doc    └────────┘           └────────┘     └────────┘
816  have hp : p ≠ 0 := mt leading_coeff_eq_zero.2 (λ h₁, h $ by rw [h₁, zero_mul]),
id                    └┘ └───────────────────┘     └┘            └┘  └──────┘
src                    └┘ └───────────────────┘                └──┘  └┘└──────┘
typ                   └┘ └───────────────────┘     └┘        └──┘└┘└┘└──────┘
doc                                                              └──┘  └┘        
txt                                                              └──┘  └┘        
par                                                              └──┘  └┘        
pid                                                                └┘  └┘        
st                                                              └─────┘└────────┘
817  have hq : q ≠ 0 := mt leading_coeff_eq_zero.2 (λ h₁, h $ by rw [h₁, mul_zero]),
id                    └┘ └───────────────────┘     └┘            └┘  └──────┘
src                    └┘ └───────────────────┘                └──┘  └┘└──────┘
typ                   └┘ └───────────────────┘     └┘        └──┘└┘└┘└──────┘
doc                                                              └──┘  └┘        
txt                                                              └──┘  └┘        
par                                                              └──┘  └┘        
pid                                                                └┘  └┘        
st                                                              └─────┘└────────┘
818  have hpq : p * q ≠ 0 := λ hpq, by rw [← coeff_mul_degree_add_degree, hpq, coeff_zero] at h;
id                         └─┘           └─────────────────────────┘  └─┘  └────────┘
src                                  └────┘└─────────────────────────┘└┘   └┘└────────┘└────┘
typ                        └─┘     └────┘└─────────────────────────┘└┘└─┘└┘└────────┘└────┘
doc                                    └────┘                           └┘   └┘          └────┘
txt                                    └────┘                           └┘   └┘          └────┘
par                                    └────┘                           └┘   └┘          └────┘
pid                                      └──┘                           └┘   └┘          └───┘
st                                    └────────────────────────────────┘└───┘└──────────┘└──────
819    exact h rfl,
id            └─┘
src    └────┘ └─┘
typ    └────┘└─┘
doc    └────┘ 
txt    └────┘ 
par    └────┘ 
pid          
st   ────────────┘
820  option.some_inj.1 (show (nat_degree (p * q) : with_bot ℕ) = nat_degree p + nat_degree q,
id   └─────────────┘         └────────┘        └──────┘    └────────┘   └────────┘ 
src  └─────────────┘         └────────┘          └──────┘    └────────┘    └────────┘
typ  └─────────────┘         └────────┘        └──────┘    └────────┘   └────────┘ 
doc                           └────────┘                         └────────┘     └────────┘
821    by rw [← degree_eq_nat_degree hpq, degree_mul_eq' h, degree_eq_nat_degree hp, degree_eq_nat_degree hq])
id              └──────────────────┘ └─┘  └────────────┘   └──────────────────┘ └┘  └──────────────────┘ └┘
src       └────┘└──────────────────┘   └┘└────────────┘ └┘└──────────────────┘  └┘└──────────────────┘  
typ       └────┘└──────────────────┘└─┘└┘└────────────┘└┘└──────────────────┘└┘└┘└──────────────────┘└┘
doc       └────┘                       └┘               └┘                      └┘                      
txt       └────┘                       └┘               └┘                      └┘                      
par       └────┘                       └┘               └┘                      └┘                      
pid         └──┘                       └┘               └┘                      └┘                      
st       └─────────────────────────────┘└────────────────┘└───────────────────────┘└───────────────────────┘
822  
823  lemma leading_coeff_mul' (h : leading_coeff p * leading_coeff q ≠ 0) :
id                                 └───────────┘   └───────────┘  
src                                └───────────┘    └───────────┘   
typ                                └───────────┘   └───────────┘  
doc                                └───────────┘     └───────────┘
824    leading_coeff (p * q) = leading_coeff p * leading_coeff q :=
id     └───────────┘       └───────────┘   └───────────┘ 
src    └───────────┘         └───────────┘    └───────────┘
typ    └───────────┘       └───────────┘   └───────────┘ 
doc    └───────────┘           └───────────┘     └───────────┘
825  begin
st   └─────
826    unfold leading_coeff,
src    └──────────────────┘
typ    └──────────────────┘
doc    └──────────────────┘
txt    └──────────────────┘
par    └──────────────────┘
pid          └────────────┘
st   ─────────────────────┘└─
827    rw [nat_degree_mul_eq' h, coeff_mul_degree_add_degree],
id         └────────────────┘   └─────────────────────────┘
src    └──┘└────────────────┘ └┘└─────────────────────────┘
typ    └──┘└────────────────┘└┘└─────────────────────────┘
doc    └──┘                   └┘                           
txt    └──┘                   └┘                           
par    └──┘                   └┘                           
pid      └┘                   └┘                           
st   ─────────────────────────┘└───────────────────────────┘└──
828    refl
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
pid        
st   ──────┘
829  end
st   └─┘
830  
831  lemma leading_coeff_pow' : leading_coeff p ^ n ≠ 0 →
id                              └───────────┘    
src                             └───────────┘      
typ                             └───────────┘    
doc                             └───────────┘
832    leading_coeff (p ^ n) = leading_coeff p ^ n :=
id     └───────────┘       └───────────┘   
src    └───────────┘         └───────────┘   
typ    └───────────┘       └───────────┘   
doc    └───────────┘           └───────────┘
833  nat.rec_on n (by simp) $
id   └────────┘ 
src  └────────┘       └──┘
typ  └────────┘      └──┘
doc                   └──┘
txt                   └──┘
par                   └──┘
st                   └───┘
834  λ n ih h,
id      └┘ 
typ     └┘ 
835  have h₁ : leading_coeff p ^ n ≠ 0 :=
id             └───────────┘    
src            └───────────┘      
typ            └───────────┘    
doc            └───────────┘
836    λ h₁, h $ by rw [pow_succ, h₁, mul_zero],
id       └┘            └──────┘  └┘  └──────┘
src                 └──┘└──────┘└┘  └┘└──────┘
typ      └┘        └──┘└──────┘└┘└┘└┘└──────┘
doc                 └──┘        └┘  └┘        
txt                 └──┘        └┘  └┘        
par                 └──┘        └┘  └┘        
pid                   └┘        └┘  └┘        
st                 └───────────┘└──┘└────────┘
837  have h₂ : leading_coeff p * leading_coeff (p ^ n) ≠ 0 :=
id             └───────────┘   └───────────┘      
src            └───────────┘    └───────────┘        
typ            └───────────┘   └───────────┘      
doc            └───────────┘     └───────────┘
838    by rwa [pow_succ, ← ih h₁] at h,
id             └──────┘    └┘ └┘
src       └───┘└──────┘└──┘    └────┘
typ       └───┘└──────┘└──┘└┘└┘└────┘
doc       └───┘        └──┘    └────┘
txt       └───┘        └──┘    └────┘
par       └───┘        └──┘    └────┘
pid          └┘        └──┘    └───┘
st       └────────────┘└───────┘└───┘
839  by rw [pow_succ, pow_succ, leading_coeff_mul' h₂, ih h₁]
id          └──────┘  └──────┘  └────────────────┘ └┘  └┘ └┘
src     └──┘└──────┘└┘└──────┘└┘└────────────────┘  └┘    └─
typ     └──┘└──────┘└┘└──────┘└┘└────────────────┘└┘└┘└┘└┘└─
doc     └──┘        └┘        └┘                    └┘    └─
txt     └──┘        └┘        └┘                    └┘    └─
par     └──┘        └┘        └┘                    └┘    └─
pid       └┘        └┘        └┘                    └┘    
st     └───────────┘└────────┘└─────────────────────┘└─────┘
840  
src  
typ  
doc  
txt  
par  
pid  
st   
841  lemma degree_pow_eq' : ∀ {n}, leading_coeff p ^ n ≠ 0 →
id                               └───────────┘    
src                                └───────────┘      
typ                              └───────────┘    
doc                                └───────────┘
842    degree (p ^ n) = add_monoid.smul n (degree p)
id     └────┘       └─────────────┘   └────┘ 
src    └────┘         └─────────────┘    └────┘
typ    └────┘       └─────────────┘   └────┘ 
doc    └────┘                              └────┘
843  | 0     := λ h, by rw [pow_zero, ← C_1] at *;
id                         └──────┘    └─┘
src                     └──┘└──────┘└──┘└─┘└────┘
typ                    └──┘└──────┘└──┘└─┘└────┘
doc                     └──┘        └──┘   └────┘
txt                     └──┘        └──┘   └────┘
par                     └──┘        └──┘   └────┘
pid                       └┘        └──┘   └───┘
st                     └───────────┘└─────┘└──────
844    rw [degree_C h, add_monoid.zero_smul]
id         └──────┘   └──────────────────┘
src    └──┘└──────┘ └┘└──────────────────┘└┘
typ    └──┘└──────┘└┘└──────────────────┘└┘
doc    └──┘         └┘                    └┘
txt    └──┘         └┘                    └┘
par    └──┘         └┘                    └┘
pid      └┘         └┘                    
st   ─────┘└────────┘└────────────────────┘
845  | (n+1) := λ h,
id              
src      
typ             
846  have h₁ : leading_coeff p ^ n ≠ 0 := λ h₁, h $
id             └───────────┘             └┘  
src            └───────────┘      
typ            └───────────┘             └┘  
doc            └───────────┘
847    by rw [pow_succ, h₁, mul_zero],
id            └──────┘  └┘  └──────┘
src       └──┘└──────┘└┘  └┘└──────┘
typ       └──┘└──────┘└┘└┘└┘└──────┘
doc       └──┘        └┘  └┘        
txt       └──┘        └┘  └┘        
par       └──┘        └┘  └┘        
pid         └┘        └┘  └┘        
st       └───────────┘└──┘└────────┘
848  have h₂ : leading_coeff p * leading_coeff (p ^ n) ≠ 0 :=
id             └───────────┘   └───────────┘       
src            └───────────┘    └───────────┘        
typ            └───────────┘   └───────────┘       
doc            └───────────┘     └───────────┘
849    by rwa [pow_succ, ← leading_coeff_pow' h₁] at h,
id             └──────┘    └────────────────┘ └┘
src       └───┘└──────┘└──┘└────────────────┘  └────┘
typ       └───┘└──────┘└──┘└────────────────┘└┘└────┘
doc       └───┘        └──┘                    └────┘
txt       └───┘        └──┘                    └────┘
par       └───┘        └──┘                    └────┘
pid          └┘        └──┘                    └───┘
st       └────────────┘└───────────────────────┘└───┘
850  by rw [pow_succ, degree_mul_eq' h₂, succ_smul, degree_pow_eq' h₁]
id          └──────┘  └────────────┘ └┘  └───────┘  └────────────┘ └┘
src     └──┘└──────┘└┘└────────────┘  └┘└───────┘└┘                └─
typ     └──┘└──────┘└┘└────────────┘└┘└┘└───────┘└┘└────────────┘└┘└─
doc     └──┘        └┘                └┘         └┘                └─
txt     └──┘        └┘                └┘         └┘                └─
par     └──┘        └┘                └┘         └┘                └─
pid       └┘        └┘                └┘         └┘                
st     └───────────┘└─────────────────┘└─────────┘└─────────────────┘
851  
src  
typ  
doc  
txt  
par  
pid  
st   
852  lemma nat_degree_pow_eq' {n : ℕ} (h : leading_coeff p ^ n ≠ 0) :
id                                        └───────────┘    
src                                       └───────────┘      
typ                                       └───────────┘    
doc                                        └───────────┘
853    nat_degree (p ^ n) = n * nat_degree p :=
id     └────────┘         └────────┘ 
src    └────────┘            └────────┘
typ    └────────┘         └────────┘ 
doc    └────────┘               └────────┘
854  if hp0 : p = 0 then
id   └┘        
src  └┘         
typ  └┘        
855    if hn0 : n = 0 then by simp *
id     └┘        
src    └┘                    └──────
typ    └┘                   └──────
doc                           └──────
txt                           └──────
par                           └──────
pid                               
st                           └───────
856    else by rw [hp0, zero_pow (nat.pos_of_ne_zero hn0)]; simp
id                 └─┘  └──────┘  └────────────────┘ └─┘
src  ─┘        └──┘   └┘└──────┘ └────────────────┘   └┘  └───┘
typ  ─┘        └──┘└─┘└┘└──────┘ └────────────────┘└─┘└┘  └───┘
doc  ─┘        └──┘   └┘                              └┘  └───┘
txt  ─┘        └──┘   └┘                              └┘  └───┘
par  ─┘        └──┘   └┘                              └┘  └───┘
pid  ─┘          └┘   └┘                              └┘      
st   ─┘       └──────┘└─────────────────────────────────┘└─────┘
857  else
858  have hpn : p ^ n ≠ 0, from λ hpn0,  have h1 : _ := h,
id   └──┘                     └──┘                  
src                  
typ  └──┘                     └──┘                  
859    by rw [← leading_coeff_pow' h1, hpn0, leading_coeff_zero] at h;
id              └────────────────┘ └┘  └──┘  └────────────────┘
src       └────┘└────────────────┘  └┘    └┘└────────────────┘└────┘
typ       └────┘└────────────────┘└┘└┘└──┘└┘└────────────────┘└────┘
doc       └────┘                    └┘    └┘                  └────┘
txt       └────┘                    └┘    └┘                  └────┘
par       └────┘                    └┘    └┘                  └────┘
pid         └──┘                    └┘    └┘                  └───┘
st       └──────────────────────────┘└────┘└──────────────────┘└──────
860    exact h rfl,
id            └─┘
src    └────┘ └─┘
typ    └────┘└─┘
doc    └────┘ 
txt    └────┘ 
par    └────┘ 
pid          
st   ────────────┘
861  option.some_inj.1 $ show (nat_degree (p ^ n) : with_bot ℕ) = (n * nat_degree p : ℕ),
id   └─────────────┘          └────────┘        └──────┘       └────────┘    
src  └─────────────┘          └────────┘          └──────┘        └────────┘     
typ  └─────────────┘          └────────┘        └──────┘       └────────┘    
doc                            └────────┘                              └────────┘
862    by rw [← degree_eq_nat_degree hpn, degree_pow_eq' h, degree_eq_nat_degree hp0,
id              └──────────────────┘ └─┘  └────────────┘   └──────────────────┘ └─┘
src       └────┘└──────────────────┘   └┘└────────────┘ └┘└──────────────────┘   └─
typ       └────┘└──────────────────┘└─┘└┘└────────────┘└┘└──────────────────┘└─┘└─
doc       └────┘                       └┘               └┘                       └─
txt       └────┘                       └┘               └┘                       └─
par       └────┘                       └┘               └┘                       └─
pid         └──┘                       └┘               └┘                       └─
st       └─────────────────────────────┘└────────────────┘└────────────────────────┘└─
863      ← with_bot.coe_smul]; simp
id         └───────────────┘
src  ─────┘└───────────────┘  └────
typ  ─────┘└───────────────┘  └────
doc  ─────┘                   └────
txt  ─────┘                   └────
par  ─────┘                   └────
pid  ─────┘                       
st   ──────────────────────┘└──────
864  
src  
typ  
doc  
txt  
par  
pid  
st   
865  @[simp] lemma leading_coeff_X_pow : ∀ n : ℕ, leading_coeff ((X : polynomial α) ^ n) = 1
id                                              └───────────┘      └────────┘      
src                                              └───────────┘      └────────┘        
typ                                             └───────────┘      └────────┘      
doc    └──┘                                       └───────────┘      └────────┘
866  | 0 := by simp
src            └───┘
typ            └───┘
doc            └───┘
txt            └───┘
par            └───┘
pid                
st            └────┘
867  | (n+1) :=
id      
src      
typ     
868  if h10 : (1 : α) = 0
id   └┘              
src  └┘               
typ  └┘              
869  then by rw [pow_succ, ← one_mul X, ← C_1, h10]; simp
id               └──────┘    └─────┘     └─┘  └─┘
src          └──┘└──────┘└──┘└─────┘└──┘└─┘└┘     └───┘
typ          └──┘└──────┘└──┘└─────┘└──┘└─┘└┘└─┘  └───┘
doc          └──┘        └──┘       └──┘   └┘     └───┘
txt          └──┘        └──┘        └──┘   └┘     └───┘
par          └──┘        └──┘        └──┘   └┘     └───┘
pid            └┘        └──┘        └──┘   └┘         
st          └───────────┘└───────────┘└─────┘└───┘└─────┘
870  else
871  have h : leading_coeff (X : polynomial α) * leading_coeff (X ^ n) ≠ 0,
id   └──┘     └───────────┘     └────────┘    └───────────┘       
src           └───────────┘     └────────┘     └───────────┘       
typ  └──┘     └───────────┘     └────────┘    └───────────┘       
doc           └───────────┘     └────────┘      └───────────┘  
872    by rw [leading_coeff_X, leading_coeff_X_pow n, one_mul];
id            └─────────────┘  └─────────────────┘   └─────┘
src       └──┘└─────────────┘└┘                    └┘└─────┘
typ       └──┘└─────────────┘└┘└─────────────────┘└┘└─────┘
doc       └──┘               └┘                    └┘       
txt       └──┘               └┘                    └┘       
par       └──┘               └┘                    └┘       
pid         └┘               └┘                    └┘       
st       └──────────────────┘└─────────────────────┘└───────┘└─
873      exact h10,
id             └─┘
src      └────┘
typ      └────┘└─┘
doc      └────┘
txt      └────┘
par      └────┘
pid           
st   ────────────┘
874  by rw [pow_succ, leading_coeff_mul' h, leading_coeff_X, leading_coeff_X_pow, one_mul]
id          └──────┘  └────────────────┘   └─────────────┘  └─────────────────┘  └─────┘
src     └──┘└──────┘└┘└────────────────┘ └┘└─────────────┘└┘                   └┘└─────┘└─
typ     └──┘└──────┘└┘└────────────────┘└┘└─────────────┘└┘└─────────────────┘└┘└─────┘└─
doc     └──┘        └┘                   └┘               └┘                   └┘       └─
txt     └──┘        └┘                   └┘               └┘                   └┘       └─
par     └──┘        └┘                   └┘               └┘                   └┘       └─
pid       └┘        └┘                   └┘               └┘                   └┘       
st     └───────────┘└────────────────────┘└───────────────┘└───────────────────┘└───────┘
875  
src  
typ  
doc  
txt  
par  
pid  
st   
876  lemma nat_degree_comp_le : nat_degree (p.comp q) ≤ nat_degree p * nat_degree q :=
id                              └────────┘  └───┘    └────────┘   └────────┘ 
src                             └────────┘   └───┘     └────────┘    └────────┘
typ                             └────────┘  └───┘    └────────┘   └────────┘ 
doc                             └────────┘              └────────┘     └────────┘
877  if h0 : p.comp q = 0 then by rw [h0, nat_degree_zero]; exact nat.zero_le _
id   └┘      └───┘                 └┘  └─────────────┘         └─────────┘
src  └┘       └───┘              └──┘  └┘└─────────────┘  └────┘└─────────┘└─┘
typ  └┘      └───┘             └──┘└┘└┘└─────────────┘  └────┘└─────────┘└─┘
doc                               └──┘  └┘                 └────┘           └─┘
txt                               └──┘  └┘                 └────┘           └─┘
par                               └──┘  └┘                 └────┘           └─┘
pid                                 └┘  └┘                                 └┘
st                               └─────┘└───────────────┘└────────────────────┘
878  else with_bot.coe_le_coe.1 $
id        └─────────────────┘  
src       └─────────────────┘
typ       └─────────────────┘  
879    calc ↑(nat_degree (p.comp q)) = degree (p.comp q) : (degree_eq_nat_degree h0).symm
id           └────────┘  └───┘      └────┘  └───┘      └──────────────────┘ └┘ └──┘
src          └────────┘   └───┘       └────┘   └───┘       └──────────────────┘    └──┘
typ          └────────┘  └───┘      └────┘  └───┘      └──────────────────┘ └┘ └──┘
doc           └────────┘               └────┘
880    ... ≤ _ : degree_sum_le _ _
id               └───────────┘
src              └───────────┘
typ              └───────────┘
881    ... ≤ _ : sup_le (λ n hn,
id               └────┘     └┘
src              └────┘
typ              └────┘     └┘
882      calc degree (C (coeff p n) * q ^ n)
id            └────┘    └───┘       
src           └────┘    └───┘         
typ           └────┘    └───┘       
doc           └────┘    └───┘
883          ≤ degree (C (coeff p n)) + degree (q ^ n) : degree_mul_le _ _
id             └────┘    └───┘      └────┘        └───────────┘
src            └────┘    └───┘        └────┘          └───────────┘
typ            └────┘    └───┘      └────┘        └───────────┘
doc            └────┘    └───┘         └────┘
884      ... ≤ nat_degree (C (coeff p n)) + add_monoid.smul n (degree q) :
id             └────────┘    └───┘      └─────────────┘   └────┘ 
src            └────────┘    └───┘        └─────────────┘    └────┘
typ            └────────┘    └───┘      └─────────────┘   └────┘ 
doc            └────────┘    └───┘                            └────┘
885        add_le_add' degree_le_nat_degree (degree_pow_le _ _)
id         └─────────┘ └──────────────────┘  └───────────┘
src        └─────────┘ └──────────────────┘  └───────────┘
typ        └─────────┘ └──────────────────┘  └───────────┘
886      ... ≤ nat_degree (C (coeff p n)) + add_monoid.smul n (nat_degree q) :
id             └────────┘    └───┘      └─────────────┘   └────────┘ 
src            └────────┘    └───┘        └─────────────┘    └────────┘
typ            └────────┘    └───┘      └─────────────┘   └────────┘ 
doc            └────────┘    └───┘                            └────────┘
887        add_le_add_left' (add_monoid.smul_le_smul_of_le_right
id         └──────────────┘  └─────────────────────────────────┘
src        └──────────────┘  └─────────────────────────────────┘
typ        └──────────────┘  └─────────────────────────────────┘
888          (@degree_le_nat_degree _ _ q) n)
id             └──────────────────┘       
src            └──────────────────┘
typ            └──────────────────┘       
889      ... = (n * nat_degree q : ℕ) :
id                └────────┘    
src                └────────┘     
typ               └────────┘    
doc                 └────────┘
890       by rw [nat_degree_C, with_bot.coe_zero, zero_add, ← with_bot.coe_smul,
id               └──────────┘  └───────────────┘  └──────┘    └───────────────┘
src          └──┘└──────────┘└┘└───────────────┘└┘└──────┘└──┘└───────────────┘└─
typ          └──┘└──────────┘└┘└───────────────┘└┘└──────┘└──┘└───────────────┘└─
doc          └──┘            └┘                 └┘        └──┘                 └─
txt          └──┘            └┘                 └┘        └──┘                 └─
par          └──┘            └┘                 └┘        └──┘                 └─
pid            └┘            └┘                 └┘        └──┘                 └─
st          └───────────────┘└─────────────────┘└────────┘└───────────────────┘└─
891         add_monoid.smul_eq_mul]; simp
id          └────────────────────┘
src  ──────┘└────────────────────┘  └────
typ  ──────┘└────────────────────┘  └────
doc  ──────┘                        └────
txt  ──────┘                        └────
par  ──────┘                        └────
pid  ──────┘                            
st   ────────────────────────────┘└──────
892      ... ≤ (nat_degree p * nat_degree q : ℕ) : with_bot.coe_le_coe.2 $
id              └────────┘   └────────┘        └─────────────────┘
src  ───┘       └────────┘    └────────┘         └─────────────────┘
typ  ───┘       └────────┘   └────────┘        └─────────────────┘
doc  ───┘       └────────┘     └────────┘
txt  ───┘
par  ───┘
pid  ───┘
st   ───┘
893        mul_le_mul_of_nonneg_right
id         └────────────────────────┘
src        └────────────────────────┘
typ        └────────────────────────┘
894          (le_nat_degree_of_ne_zero (finsupp.mem_support_iff.1 hn))
id            └──────────────────────┘  └─────────────────────┘  └┘
src           └──────────────────────┘  └─────────────────────┘
typ           └──────────────────────┘  └─────────────────────┘  └┘
895          (nat.zero_le _))
id            └─────────┘
src           └─────────┘
typ           └─────────┘
896  
897  lemma degree_map_le [comm_semiring β] (f : α → β) [is_semiring_hom f] :
id                        └───────────┘              └─────────────┘ 
src                       └───────────┘                 └─────────────┘
typ                       └───────────┘              └─────────────┘ 
doc                                                     └─────────────┘
898    degree (p.map f) ≤ degree p :=
id     └────┘  └──┘    └────┘ 
src    └────┘   └──┘     └────┘
typ    └────┘  └──┘    └────┘ 
doc    └────┘   └──┘      └────┘
899  if h : p.map f = 0 then by simp [h]
id   └┘     └──┘                   
src  └┘      └──┘              └────┘ └┘
typ  └┘     └──┘             └────┘└┘
doc          └──┘               └────┘ └┘
txt                             └────┘ └┘
par                             └────┘ └┘
pid                                  
st                             └────────┘
900  else begin
st        └─────
901    rw [degree_eq_nat_degree h],
id         └──────────────────┘ 
src    └──┘└──────────────────┘ 
typ    └──┘└──────────────────┘
doc    └──┘                     
txt    └──┘                     
par    └──┘                     
pid      └┘                     
st   ───────────────────────────┘└──
902    refine le_degree_of_ne_zero (mt (congr_arg f) _),
id            └──────────────────┘  └┘  └───────┘ 
src    └─────┘└──────────────────┘ └┘ └───────┘ └──┘
typ    └─────┘└──────────────────┘ └┘ └───────┘└──┘
doc    └─────┘                                  └──┘
txt    └─────┘                                  └──┘
par    └─────┘                                  └──┘
pid                                            └──┘
st   ─────────────────────────────────────────────────┘└─
903    rw [← coeff_map f, is_semiring_hom.map_zero f],
id           └───────┘   └──────────────────────┘ 
src    └────┘└───────┘ └┘└──────────────────────┘ 
typ    └────┘└───────┘└┘└──────────────────────┘
doc    └────┘          └┘                         
txt    └────┘          └┘                         
par    └────┘          └┘                         
pid      └──┘          └┘                         
st   ──────────────────┘└──────────────────────────┘└──
904    exact mt leading_coeff_eq_zero.1 h
id           └┘ └───────────────────┘   
src    └────┘└┘└───────────────────┘└─┘ 
typ    └────┘└┘└───────────────────┘└─┘
doc    └────┘                       └─┘ 
txt    └────┘                       └─┘ 
par    └────┘                       └─┘ 
pid                                └─┘ 
st   ────────────────────────────────────┘
905  end
id   └─┘
typ  └─┘
st   └─┘
906  
907  lemma subsingleton_of_monic_zero (h : monic (0 : polynomial α)) :
id                                         └───┘      └────────┘ 
src                                        └───┘      └────────┘
typ                                        └───┘      └────────┘ 
doc                                        └───┘      └────────┘
908    (∀ p q : polynomial α, p = q) ∧ (∀ a b : α, a = b) :=
id              └────────┘                     
src             └────────┘                         
typ             └────────┘                     
doc             └────────┘
909  by rw [monic.def, leading_coeff_zero] at h;
id          └───────┘  └────────────────┘
src     └──┘└───────┘└┘└────────────────┘└────┘
typ     └──┘└───────┘└┘└────────────────┘└────┘
doc     └──┘         └┘                  └────┘
txt     └──┘         └┘                  └────┘
par     └──┘         └┘                  └────┘
pid       └┘         └┘                  └───┘
st     └────────────┘└──────────────────┘└──────
910    exact ⟨λ p q, by rw [← mul_one p, ← mul_one q, ← C_1, ← h, C_0, mul_zero, mul_zero],
id                            └─────┘     └─────┘     └─┘      └─┘  └──────┘  └──────┘
src    └────┘  └────┘  └────┘└─────┘ └──┘└─────┘ └──┘└─┘└──┘ └┘└─┘└┘└──────┘└┘└──────┘└─
typ    └────┘  └────┘  └────┘└─────┘└──┘└─────┘└──┘└─┘└──┘└┘└─┘└┘└──────┘└┘└──────┘└─
doc    └────┘  └────┘  └────┘        └──┘        └──┘   └──┘ └┘   └┘        └┘        └─
txt    └────┘  └────┘  └────┘        └──┘        └──┘   └──┘ └┘   └┘        └┘        └─
par    └────┘  └────┘  └────┘        └──┘        └──┘   └──┘ └┘   └┘        └┘        └─
pid           └────┘  └─────┘        └──┘        └──┘   └──┘ └┘   └┘        └┘        └──
st   ─────────────────┘└──────────────┘└───────────┘└─────┘└───┘└───┘└────────┘└────────┘└─
911      λ a b, by rw [← mul_one a, ← mul_one b, ← h, mul_zero, mul_zero]⟩
id                       └─────┘     └─────┘       └──────┘  └──────┘
src  ───┘ └────┘  └────┘└─────┘ └──┘└─────┘ └──┘ └┘└──────┘└┘└──────┘└─
typ  ───┘ └────┘  └────┘└─────┘└──┘└─────┘└──┘└┘└──────┘└┘└──────┘└─
doc  ───┘ └────┘  └────┘        └──┘        └──┘ └┘        └┘        └─
txt  ───┘ └────┘  └────┘        └──┘        └──┘ └┘        └┘        └─
par  ───┘ └────┘  └────┘        └──┘        └──┘ └┘        └┘        └─
pid  ───┘ └────┘  └─────┘        └──┘        └──┘ └┘        └┘        └┘
st   ────────────┘└──────────────┘└───────────┘└───┘└────────┘└────────┘└─
912  
src  
typ  
doc  
txt  
par  
pid  
st   
913  lemma degree_map_eq_of_leading_coeff_ne_zero [comm_semiring β] (f : α → β)
id                                                 └───────────┘           
src                                                └───────────┘
typ                                                └───────────┘           
914    [is_semiring_hom f] (hf : f (leading_coeff p) ≠ 0) : degree (p.map f) = degree p :=
id      └─────────────┘           └───────────┘         └────┘  └──┘    └────┘ 
src     └─────────────┘             └───────────┘          └────┘   └──┘     └────┘
typ     └─────────────┘           └───────────┘         └────┘  └──┘    └────┘ 
doc     └─────────────┘             └───────────┘           └────┘   └──┘      └────┘
915  le_antisymm (degree_map_le f) $
id   └─────────┘  └───────────┘ 
src  └─────────┘  └───────────┘
typ  └─────────┘  └───────────┘ 
916    have hp0 : p ≠ 0, from λ hp0, by simpa [hp0, is_semiring_hom.map_zero f] using hf,
id                            └─┘            └─┘  └──────────────────────┘         └┘
src                                    └─────┘   └┘└──────────────────────┘ └──────┘
typ                           └─┘     └─────┘└─┘└┘└──────────────────────┘└──────┘└┘
doc                                     └─────┘   └┘                         └──────┘
txt                                     └─────┘   └┘                         └──────┘
par                                     └─────┘   └┘                         └──────┘
pid                                             └┘                         └────┘
st                                     └───────────────────────────────────────────────┘
917    begin
st     └─────
918      rw [degree_eq_nat_degree hp0],
id           └──────────────────┘ └─┘
src      └──┘└──────────────────┘   
typ      └──┘└──────────────────┘└─┘
doc      └──┘                       
txt      └──┘                       
par      └──┘                       
pid        └┘                       
st   ───────────────────────────────┘└──
919      refine le_degree_of_ne_zero _,
id              └──────────────────┘
src      └─────┘└──────────────────┘└┘
typ      └─────┘└──────────────────┘└┘
doc      └─────┘                    └┘
txt      └─────┘                    └┘
par      └─────┘                    └┘
pid                                └┘
st   ────────────────────────────────┘└─
920      rw [coeff_map], exact hf
id           └───────┘         └┘
src      └──┘└───────┘  └────┘  
typ      └──┘└───────┘  └────┘└┘
doc      └──┘           └────┘  
txt      └──┘           └────┘  
par      └──┘           └────┘  
pid        └┘                  
st   ────────────────┘└───────────
921    end
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘└─┘
922  
923  lemma monic_map [comm_semiring β] (f : α → β)
id                    └───────────┘           
src                   └───────────┘
typ                   └───────────┘           
924    [is_semiring_hom f] (hp : monic p) : monic (p.map f) :=
id      └─────────────┘         └───┘     └───┘  └──┘ 
src     └─────────────┘          └───┘      └───┘   └──┘
typ     └─────────────┘         └───┘     └───┘  └──┘ 
doc     └─────────────┘          └───┘      └───┘   └──┘
925  if h : (0 : β) = 1 then
id   └┘            
src  └┘             
typ  └┘            
926    by haveI := subsingleton_of_zero_eq_one β h;
id                 └─────────────────────────┘  
src       └───────┘└─────────────────────────┘ 
typ       └───────┘└─────────────────────────┘
doc       └───────┘└─────────────────────────┘ 
txt       └───────┘                            
par       └───────┘                            
pid            └─┘                            
st       └──────────────────────────────────────────
927    exact subsingleton.elim _ _
id           └───────────────┘
src    └────┘└───────────────┘└───┘
typ    └────┘└───────────────┘└───┘
doc    └────┘                 └───┘
txt    └────┘                 └───┘
par    └────┘                 └───┘
pid                          └──┘
st   ─────────────────────────────┘
928  else
929  have f (leading_coeff p) ≠ 0,
id   └──┘   └───────────┘   
src          └───────────┘    
typ  └──┘   └───────────┘   
doc          └───────────┘
930    by rwa [show _ = _, from hp, is_semiring_hom.map_one f, ne.def, eq_comm],
id                             └┘  └─────────────────────┘   └────┘  └─────┘
src       └───┘    └─┘└───────┘  └┘└─────────────────────┘ └┘└────┘└┘└─────┘
typ       └───┘    └─┘└───────┘└┘└┘└─────────────────────┘└┘└────┘└┘└─────┘
doc       └───┘    └─┘ └───────┘  └┘                        └┘      └┘       
txt       └───┘    └─┘ └───────┘  └┘                        └┘      └┘       
par       └───┘    └─┘ └───────┘  └┘                        └┘      └┘       
pid          └┘    └─┘ └───────┘  └┘                        └┘      └┘       
st       └───────────────────────┘└─────────────────────────┘└──────┘└───────┘
931  by erw [monic, leading_coeff, nat_degree_eq_of_degree_eq
id           └───┘  └───────────┘  └────────────────────────┘
src     └───┘└───┘└┘└───────────┘└┘└────────────────────────┘
typ     └───┘└───┘└┘└───────────┘└┘└────────────────────────┘
doc     └───┘└───┘└┘└───────────┘└┘                          
txt     └───┘     └┘             └┘                          
par     └───┘     └┘             └┘                          
pid        └┘     └┘             └┘                          
st     └─────────┘└─────────────┘└────────────────────────────
932      (degree_map_eq_of_leading_coeff_ne_zero f this), coeff_map,
id        └────────────────────────────────────┘  └──┘   └───────┘
src  ───┘ └────────────────────────────────────┘     └─┘└───────┘└─
typ  ───┘ └────────────────────────────────────┘└──┘└─┘└───────┘└─
doc  ───┘                                            └─┘         └─
txt  ───┘                                            └─┘         └─
par  ───┘                                            └─┘         └─
pid  ───┘                                            └─┘         └─
st   ──────────────────────────────────────────────────┘└─────────┘└─
933      ← leading_coeff, show _ = _, from hp, is_semiring_hom.map_one f]
id         └───────────┘                  └┘  └─────────────────────┘ 
src  ─────┘└───────────┘└┘    └─┘ └───────┘  └┘└─────────────────────┘ └─
typ  ─────┘└───────────┘└┘    └─┘└───────┘└┘└┘└─────────────────────┘└─
doc  ─────┘└───────────┘└┘    └─┘ └───────┘  └┘                        └─
txt  ─────┘             └┘    └─┘ └───────┘  └┘                        └─
par  ─────┘             └┘    └─┘ └───────┘  └┘                        └─
pid  ─────┘             └┘    └─┘ └───────┘  └┘                        
st   ──────────────────┘└───────────────────┘└─────────────────────────┘
934  
src  
typ  
doc  
txt  
par  
pid  
st   
935  lemma zero_le_degree_iff {p : polynomial α} : 0 ≤ degree p ↔ p ≠ 0 :=
id                                 └────────┘        └────┘    
src                                └────────┘         └────┘      
typ                                └────────┘        └────┘    
doc                                └────────┘          └────┘
936  by rw [ne.def, ← degree_eq_bot];
id          └────┘    └───────────┘
src     └──┘└────┘└──┘└───────────┘
typ     └──┘└────┘└──┘└───────────┘
doc     └──┘      └──┘             
txt     └──┘      └──┘             
par     └──┘      └──┘             
pid       └┘      └──┘             
st     └─────────┘└───────────────┘└─
937    cases degree p; exact dec_trivial
id           └────┘         └─────────┘
src    └────┘└────┘   └────┘└─────────┘
typ    └────┘└────┘  └────┘└─────────┘
doc    └────┘└────┘   └────┘└─────────┘
txt    └────┘         └────┘           
par    └────┘         └────┘           
pid                                  
st   ────────────────────────────────────
938  
src  
typ  
doc  
txt  
par  
pid  
st   
939  @[simp] lemma coeff_mul_X_zero (p : polynomial α) : coeff (p * X) 0 = 0 :=
id                                       └────────┘     └───┘        
src                                      └────────┘      └───┘         
typ                                      └────────┘     └───┘        
doc    └──┘                              └────────┘      └───┘      
940  by rw [coeff_mul, nat.antidiagonal_zero];
id          └───────┘  └───────────────────┘
src     └──┘└───────┘└┘└───────────────────┘
typ     └──┘└───────┘└┘└───────────────────┘
doc     └──┘         └┘└───────────────────┘
txt     └──┘         └┘                     
par     └──┘         └┘                     
pid       └┘         └┘                     
st     └────────────┘└─────────────────────┘└─
941  simp only [polynomial.coeff_X_zero, finset.insert_empty_eq_singleton, finset.sum_singleton, mul_zero]
id              └─────────────────────┘  └──────────────────────────────┘  └──────────────────┘  └──────┘
src  └─────────┘└─────────────────────┘└┘└──────────────────────────────┘└┘└──────────────────┘└┘└──────┘└─
typ  └─────────┘└─────────────────────┘└┘└──────────────────────────────┘└┘└──────────────────┘└┘└──────┘└─
doc  └─────────┘                       └┘                                └┘                    └┘        └─
txt  └─────────┘                       └┘                                └┘                    └┘        └─
par  └─────────┘                       └┘                                └┘                    └┘        └─
pid      └──┘└┘                       └┘                                └┘                    └┘        
st   ──────────────────────────────────────────────────────────────────────────────────────────────────────
942  
src  
typ  
doc  
txt  
par  
pid  
st   
943  end comm_semiring
944  
945  instance subsingleton [subsingleton α] [comm_semiring α] : subsingleton (polynomial α) :=
id                          └──────────┘    └───────────┘     └──────────┘  └────────┘ 
src                         └──────────┘     └───────────┘      └──────────┘  └────────┘
typ                         └──────────┘    └───────────┘     └──────────┘  └────────┘ 
doc                                                                           └────────┘
946  ⟨λ _ _, ext (λ _, subsingleton.elim _ _)⟩
id         └─┘      └───────────────┘
src          └─┘       └───────────────┘
typ        └─┘      └───────────────┘
947  
948  section comm_semiring
949  
950  variables [comm_semiring α] {p q r : polynomial α}
id              └───────────┘             └────────┘
src             └───────────┘             └────────┘
typ             └───────────┘             └────────┘
doc                                       └────────┘
951  
952  lemma ne_zero_of_monic_of_zero_ne_one (hp : monic p) (h : (0 : α) ≠ 1) :
id                                               └───┘               
src                                              └───┘                 
typ                                              └───┘               
doc                                              └───┘
953    p ≠ 0 := mt (congr_arg leading_coeff) $ by rw [monic.def.1 hp, leading_coeff_zero]; cc
id            └┘  └───────┘ └───────────┘           └───────┘   └┘  └────────────────┘
src            └┘  └───────┘ └───────────┘       └──┘└───────┘└─┘  └┘└────────────────┘  └──
typ           └┘  └───────┘ └───────────┘       └──┘└───────┘└─┘└┘└┘└────────────────┘  └──
doc                           └───────────┘       └──┘         └─┘  └┘                    └──
txt                                               └──┘         └─┘  └┘                    └──
par                                               └──┘         └─┘  └┘                    └──
pid                                                 └┘         └─┘  └┘                      
st                                               └─────────────────┘└──────────────────┘└────
954  
src  
typ  
doc  
txt  
par  
pid  
st   
955  lemma eq_X_add_C_of_degree_le_one (h : degree p ≤ 1) :
id                                          └────┘  
src                                         └────┘   
typ                                         └────┘  
doc                                         └────┘
956    p = C (p.coeff 1) * X + C (p.coeff 0) :=
id         └────┘         └────┘
src          └────┘          └────┘
typ        └────┘         └────┘
doc           └────┘            └────┘
957  ext (λ n, nat.cases_on n (by simp)
id   └─┘      └──────────┘ 
src  └─┘       └──────────┘       └──┘
typ  └─┘      └──────────┘      └──┘
doc                               └──┘
txt                               └──┘
par                               └──┘
st                               └───┘
958    (λ n, nat.cases_on n (by simp [coeff_C])
id          └──────────┘            └─────┘
src          └──────────┘       └────┘└─────┘
typ         └──────────┘      └────┘└─────┘
doc                             └────┘       
txt                             └────┘       
par                             └────┘       
pid                                        
st                             └─────────────┘
959      (λ m, have degree p < m.succ.succ, from lt_of_le_of_lt h dec_trivial,
id                 └────┘   └────────┘       └────────────┘  └─────────┘
src                 └────┘     └────────┘       └────────────┘   └─────────┘
typ                └────┘   └────────┘       └────────────┘  └─────────┘
doc                 └────┘                                        └─────────┘
960        by simp [coeff_eq_zero_of_degree_lt this, coeff_C, nat.succ_ne_zero, coeff_X,
id                  └────────────────────────┘ └──┘  └─────┘  └──────────────┘  └─────┘
src           └────┘└────────────────────────┘    └┘└─────┘└┘└──────────────┘└┘└─────┘└─
typ           └────┘└────────────────────────┘└──┘└┘└─────┘└┘└──────────────┘└┘└─────┘└─
doc           └────┘                              └┘       └┘                └┘       └─
txt           └────┘                              └┘       └┘                └┘       └─
par           └────┘                              └┘       └┘                └┘       └─
pid                                             └┘       └┘                └┘       └─
st           └───────────────────────────────────────────────────────────────────────────
961          nat.succ_inj', @eq_comm ℕ 0])))
id           └───────────┘   └─────┘
src  ───────┘└───────────┘└┘ └─────┘ └─┘
typ  ───────┘└───────────┘└┘ └─────┘ └─┘
doc  ───────┘             └┘         └─┘
txt  ───────┘             └┘         └─┘
par  ───────┘             └┘         └─┘
pid  ───────┘             └┘         └─┘
st   ───────────────────────────────────┘
962  
963  lemma eq_X_add_C_of_degree_eq_one (h : degree p = 1) :
id                                          └────┘  
src                                         └────┘   
typ                                         └────┘  
doc                                         └────┘
964    p = C (p.leading_coeff) * X + C (p.coeff 0) :=
id         └────────────┘       └────┘
src          └────────────┘        └────┘
typ        └────────────┘       └────┘
doc           └────────────┘          └────┘
965  (eq_X_add_C_of_degree_le_one (show degree p ≤ 1, from h ▸ le_refl _)).trans
id    └─────────────────────────┘       └────┘             └─────┘    └───┘
src   └─────────────────────────┘       └────┘               └─────┘    └───┘
typ   └─────────────────────────┘       └────┘             └─────┘    └───┘
doc                                     └────┘
966    (by simp [leading_coeff, nat_degree_eq_of_degree_eq_some h])
id               └───────────┘  └─────────────────────────────┘ 
src        └────┘└───────────┘└┘└─────────────────────────────┘ 
typ        └────┘└───────────┘└┘└─────────────────────────────┘
doc        └────┘└───────────┘└┘                                
txt        └────┘             └┘                                
par        └────┘             └┘                                
pid                         └┘                                
st        └──────────────────────────────────────────────────────┘
967  
968  theorem degree_C_mul_X_pow_le (r : α) (n : ℕ) : degree (C r * X^n) ≤ n :=
id                                                 └────┘        
src                                                 └────┘         
typ                                                └────┘        
doc                                                  └────┘       
969  begin
st   └─────
970    rw [← single_eq_C_mul_X],
id           └───────────────┘
src    └────┘└───────────────┘
typ    └────┘└───────────────┘
doc    └────┘                 
txt    └────┘                 
par    └────┘                 
pid      └──┘                 
st   ────────────────────────┘└──
971    refine finset.sup_le (λ b hb, _),
id            └───────────┘
src    └─────┘└───────────┘  └───────┘
typ    └─────┘└───────────┘  └───────┘
doc    └─────┘               └───────┘
txt    └─────┘               └───────┘
par    └─────┘               └───────┘
pid                         └───────┘
st   ─────────────────────────────────┘└─
972    rw list.eq_of_mem_singleton (finsupp.support_single_subset hb),
id        └──────────────────────┘  └───────────────────────────┘ └┘
src    └─┘└──────────────────────┘ └───────────────────────────┘  
typ    └─┘└──────────────────────┘ └───────────────────────────┘└┘
doc    └─┘                                                        
txt    └─┘                                                        
par    └─┘                                                        
pid                                                              
st   ───────────────────────────────────────────────────────────────┘└─
973    exact le_refl _
id           └─────┘
src    └────┘└─────┘└─┘
typ    └────┘└─────┘└─┘
doc    └────┘       └─┘
txt    └────┘       └─┘
par    └────┘       └─┘
pid                └┘
st   ─────────────────┘
974  end
st   └─┘
975  
976  theorem degree_X_pow_le (n : ℕ) : degree (X^n : polynomial α) ≤ n :=
id                                    └────┘     └────────┘    
src                                   └────┘      └────────┘    
typ                                   └────┘     └────────┘    
doc                                    └────┘       └────────┘
977  by simpa only [C_1, one_mul] using degree_C_mul_X_pow_le (1:α) n
id                  └─┘  └─────┘        └───────────────────┘      
src     └──────────┘└─┘└┘└─────┘└──────┘└───────────────────┘ └┘ └┘ 
typ     └──────────┘└─┘└┘└─────┘└──────┘└───────────────────┘ └┘└┘
doc     └──────────┘   └┘       └──────┘                      └┘ └┘ 
txt     └──────────┘   └┘       └──────┘                      └┘ └┘ 
par     └──────────┘   └┘       └──────┘                      └┘ └┘ 
pid          └──┘└┘   └┘       └────┘                      └┘ └┘ 
st     └──────────────────────────────────────────────────────────────
978  
src  
typ  
doc  
txt  
par  
pid  
st   
979  theorem degree_X_le : degree (X : polynomial α) ≤ 1 :=
id                         └────┘     └────────┘   
src                        └────┘     └────────┘    
typ                        └────┘     └────────┘   
doc                        └────┘     └────────┘
980  by simpa only [C_1, one_mul, pow_one] using degree_C_mul_X_pow_le (1:α) 1
id                  └─┘  └─────┘  └─────┘        └───────────────────┘    
src     └──────────┘└─┘└┘└─────┘└┘└─────┘└──────┘└───────────────────┘ └┘ └───
typ     └──────────┘└─┘└┘└─────┘└┘└─────┘└──────┘└───────────────────┘ └┘└───
doc     └──────────┘   └┘       └┘       └──────┘                      └┘ └───
txt     └──────────┘   └┘       └┘       └──────┘                      └┘ └───
par     └──────────┘   └┘       └┘       └──────┘                      └┘ └───
pid          └──┘└┘   └┘       └┘       └────┘                      └┘ └┘└─
st     └───────────────────────────────────────────────────────────────────────
981  
src  
typ  
doc  
txt  
par  
pid  
st   
982  section injective
983  open function
984  variables [comm_semiring β] {f : α → β} [is_semiring_hom f] (hf : function.injective f)
id              └───────────┘                 └─────────────┘          └────────────────┘
src             └───────────┘                 └─────────────┘          └────────────────┘
typ             └───────────┘                 └─────────────┘          └────────────────┘
doc                                           └─────────────┘
985  include hf
986  
987  lemma degree_map_eq_of_injective (p : polynomial α) : degree (p.map f) = degree p :=
id                                         └────────┘     └────┘  └──┘    └────┘ 
src                                        └────────┘      └────┘   └──┘     └────┘
typ                                        └────────┘     └────┘  └──┘    └────┘ 
doc                                        └────────┘      └────┘   └──┘      └────┘
988  if h : p = 0 then by simp [h]
id   └┘                       
src  └┘                  └────┘ └┘
typ  └┘                 └────┘└┘
doc                       └────┘ └┘
txt                       └────┘ └┘
par                       └────┘ └┘
pid                            
st                       └────────┘
989  else degree_map_eq_of_leading_coeff_ne_zero _
id        └────────────────────────────────────┘
src       └────────────────────────────────────┘
typ       └────────────────────────────────────┘
990    (by rw [← is_semiring_hom.map_zero f]; exact mt hf.eq_iff.1
id               └──────────────────────┘             └───────┘
src        └────┘└──────────────────────┘   └────┘  └───────┘└──
typ        └────┘└──────────────────────┘  └────┘  └───────┘└──
doc        └────┘                           └────┘           └──
txt        └────┘                           └────┘           └──
par        └────┘                           └────┘           └──
pid          └──┘                                           └──
st        └───────────────────────────────┘└──────────────────────
991      (mt leading_coeff_eq_zero.1 h))
id        └┘ └───────────────────┘   
src  ───┘ └┘└───────────────────┘└─┘ 
typ  ───┘ └┘└───────────────────┘└─┘
doc  ───┘                        └─┘ 
txt  ───┘                        └─┘ 
par  ───┘                        └─┘ 
pid  ───┘                        └─┘ 
st   ─────────────────────────────────┘
992  
993  lemma degree_map' (p : polynomial α) :
id                          └────────┘ 
src                         └────────┘
typ                         └────────┘ 
doc                         └────────┘
994    degree (p.map f) = degree p :=
id     └────┘  └──┘    └────┘ 
src    └────┘   └──┘     └────┘
typ    └────┘  └──┘    └────┘ 
doc    └────┘   └──┘      └────┘
995  p.degree_map_eq_of_injective hf
id   └─────────────────────────┘ └┘
src   └─────────────────────────┘
typ  └─────────────────────────┘ └┘
996  
997  lemma nat_degree_map' (p : polynomial α) :
id                              └────────┘ 
src                             └────────┘
typ                             └────────┘ 
doc                             └────────┘
998    nat_degree (p.map f) = nat_degree p :=
id     └────────┘  └──┘    └────────┘ 
src    └────────┘   └──┘     └────────┘
typ    └────────┘  └──┘    └────────┘ 
doc    └────────┘   └──┘      └────────┘
999  nat_degree_eq_of_degree_eq (degree_map' hf p)
id   └────────────────────────┘  └─────────┘ └┘ 
src  └────────────────────────┘  └─────────┘
typ  └────────────────────────┘  └─────────┘ └┘ 
1000  
1001  lemma map_injective (p : polynomial α) :
id                            └────────┘ 
src                           └────────┘
typ                           └────────┘ 
doc                           └────────┘
1002    injective (map f : polynomial α → polynomial β) :=
id     └───────┘  └─┘    └────────┘    └────────┘ 
src    └───────┘  └─┘     └────────┘     └────────┘
typ    └───────┘  └─┘    └────────┘    └────────┘ 
doc               └─┘     └────────┘     └────────┘
1003  λ p q h, ext $ λ m, hf $
id         └─┘       └┘
src           └─┘
typ        └─┘       └┘
1004  begin
st   └─────
1005    rw ext_iff at h,
id        └─────┘
src    └─┘└─────┘└───┘
typ    └─┘└─────┘└───┘
doc    └─┘       └───┘
txt    └─┘       └───┘
par    └─┘       └───┘
pid             └───┘
st   ────────────────┘└─
1006    specialize h m,
id                 
src    └─────────┘ 
typ    └─────────┘
doc    └─────────┘ 
txt    └─────────┘ 
par    └─────────┘ 
pid               
st   ───────────────┘└─
1007    rw [coeff_map f, coeff_map f] at h,
id         └───────┘   └───────┘ 
src    └──┘└───────┘ └┘└───────┘ └────┘
typ    └──┘└───────┘└┘└───────┘└────┘
doc    └──┘          └┘          └────┘
txt    └──┘          └┘          └────┘
par    └──┘          └┘          └────┘
pid      └┘          └┘          └───┘
st   ────────────────┘└───────────┘└───┘└─
1008    exact h
id           
src    └────┘ 
typ    └────┘
doc    └────┘ 
txt    └────┘ 
par    └────┘ 
pid          
st   ─────────┘
1009  end
st   └─┘
1010  
1011  lemma leading_coeff_of_injective (p : polynomial α) :
id                                         └────────┘ 
src                                        └────────┘
typ                                        └────────┘ 
doc                                        └────────┘
1012    leading_coeff (p.map f) = f (leading_coeff p) :=
id     └───────────┘  └──┘      └───────────┘ 
src    └───────────┘   └──┘        └───────────┘
typ    └───────────┘  └──┘      └───────────┘ 
doc    └───────────┘   └──┘         └───────────┘
1013  begin
st   └─────
1014    delta leading_coeff,
src    └─────────────────┘
typ    └─────────────────┘
doc    └─────────────────┘
txt    └─────────────────┘
par    └─────────────────┘
pid         └────────────┘
st   ────────────────────┘└─
1015    rw [coeff_map f, nat_degree_map' hf p]
id         └───────┘   └─────────────┘ └┘ 
src    └──┘└───────┘ └┘└─────────────┘   └┘
typ    └──┘└───────┘└┘└─────────────┘└┘└┘
doc    └──┘          └┘                  └┘
txt    └──┘          └┘                  └┘
par    └──┘          └┘                  └┘
pid      └┘          └┘                  
st   ────────────────┘└────────────────────┘
1016  end
st   └─┘
1017  
1018  lemma monic_of_injective {p : polynomial α} (hp : (p.map f).monic) : p.monic :=
id                                 └────────┘          └──┘  └───┘     └────┘
src                                └────────┘            └──┘   └───┘      └────┘
typ                                └────────┘          └──┘  └───┘     └────┘
doc                                └────────┘            └──┘   └───┘      └────┘
1019  begin
st   └─────
1020    apply hf,
src    └────┘
typ    └────┘
doc    └────┘
txt    └────┘
par    └────┘
pid         
st   ─────────┘└─
1021    rw [← leading_coeff_of_injective hf, hp.leading_coeff, is_semiring_hom.map_one f]
id           └────────────────────────┘ └┘                    └─────────────────────┘ 
src    └────┘└────────────────────────┘  └┘                └┘└─────────────────────┘ └┘
typ    └────┘└────────────────────────┘└┘└┘└──────────────┘└┘└─────────────────────┘└┘
doc    └────┘                            └┘                └┘                        └┘
txt    └────┘                            └┘                └┘                        └┘
par    └────┘                            └┘                └┘                        └┘
pid      └──┘                            └┘                └┘                        
st   ────────────────────────────────────┘└────────────────┘└─────────────────────────┘
1022  end
st   └─┘
1023  
1024  end injective
1025  
1026  theorem monic_of_degree_le (n : ℕ) (H1 : degree p ≤ n) (H2 : coeff p n = 1) : monic p :=
id                                           └────┘           └───┘         └───┘ 
src                                          └────┘             └───┘           └───┘
typ                                          └────┘           └───┘         └───┘ 
doc                                           └────┘              └───┘            └───┘
1027  decidable.by_cases
id   └────────────────┘
src  └────────────────┘
typ  └────────────────┘
1028    (assume H : degree p < n, @subsingleton.elim _ (subsingleton_of_zero_eq_one α $
id                 └────┘      └───────────────┘    └─────────────────────────┘ 
src                └────┘        └───────────────┘    └─────────────────────────┘
typ                └────┘      └───────────────┘    └─────────────────────────┘ 
doc                └────┘                              └─────────────────────────┘
1029      H2 ▸ (coeff_eq_zero_of_degree_lt H).symm) _ _)
id       └┘   └────────────────────────┘  └──┘
src           └────────────────────────┘   └──┘
typ      └┘   └────────────────────────┘  └──┘
1030    (assume H : ¬degree p < n, by rwa [monic, leading_coeff, nat_degree, (lt_or_eq_of_le H1).resolve_left H])
id                 └────┘             └───┘  └───────────┘  └────────┘   └────────────┘ └┘               
src                └────┘          └───┘└───┘└┘└───────────┘└┘└────────┘└┘ └────────────┘  └─────────────┘ 
typ                └────┘        └───┘└───┘└┘└───────────┘└┘└────────┘└┘ └────────────┘└┘└─────────────┘
doc                 └────┘           └───┘└───┘└┘└───────────┘└┘└────────┘└┘                 └─────────────┘ 
txt                                  └───┘     └┘             └┘          └┘                 └─────────────┘ 
par                                  └───┘     └┘             └┘          └┘                 └─────────────┘ 
pid                                     └┘     └┘             └┘          └┘                 └─────────────┘ 
st                                  └─────────┘└─────────────┘└──────────┘└──────────────────────────────────┘
1031  
1032  theorem monic_X_pow_add {n : ℕ} (H : degree p ≤ n) : monic (X ^ (n+1) + p) :=
id                                       └────┘       └───┘         
src                                      └────┘         └───┘         
typ                                      └────┘       └───┘         
doc                                       └────┘          └───┘  
1033  have H1 : degree p < n+1, from lt_of_le_of_lt H (with_bot.coe_lt_coe.2 (nat.lt_succ_self n)),
id             └────┘           └────────────┘   └─────────────────┘   └──────────────┘ 
src            └────┘             └────────────┘    └─────────────────┘   └──────────────┘
typ            └────┘           └────────────┘   └─────────────────┘   └──────────────┘ 
doc            └────┘
1034  monic_of_degree_le (n+1)
id   └────────────────┘  
src  └────────────────┘   
typ  └────────────────┘  
1035    (le_trans (degree_add_le _ _) (max_le (degree_X_pow_le _) (le_of_lt H1)))
id      └──────┘  └───────────┘       └────┘  └─────────────┘     └──────┘ └┘
src     └──────┘  └───────────┘       └────┘  └─────────────┘     └──────┘
typ     └──────┘  └───────────┘       └────┘  └─────────────┘     └──────┘ └┘
1036    (by rw [coeff_add, coeff_X_pow, if_pos rfl, coeff_eq_zero_of_degree_lt H1, add_zero])
id             └───────┘  └─────────┘  └────┘ └─┘  └────────────────────────┘ └┘  └──────┘
src        └──┘└───────┘└┘└─────────┘└┘└────┘└─┘└┘└────────────────────────┘  └┘└──────┘
typ        └──┘└───────┘└┘└─────────┘└┘└────┘└─┘└┘└────────────────────────┘└┘└┘└──────┘
doc        └──┘         └┘           └┘         └┘                            └┘        
txt        └──┘         └┘           └┘         └┘                            └┘        
par        └──┘         └┘           └┘         └┘                            └┘        
pid          └┘         └┘           └┘         └┘                            └┘        
st        └────────────┘└───────────┘└──────────┘└─────────────────────────────┘└────────┘
1037  
1038  theorem monic_X_add_C (x : α) : monic (X + C x) :=
id                                  └───┘     
src                                  └───┘    
typ                                 └───┘     
doc                                  └───┘     
1039  pow_one (X : polynomial α) ▸ monic_X_pow_add degree_C_le
id   └─────┘     └────────┘    └─────────────┘ └─────────┘
src  └─────┘     └────────┘     └─────────────┘ └─────────┘
typ  └─────┘     └────────┘    └─────────────┘ └─────────┘
doc              └────────┘
1040  
1041  theorem degree_le_iff_coeff_zero (f : polynomial α) (n : with_bot ℕ) :
id                                         └────────┘        └──────┘ 
src                                        └────────┘         └──────┘ 
typ                                        └────────┘        └──────┘ 
doc                                        └────────┘
1042    degree f ≤ n ↔ ∀ m : ℕ, n < m → coeff f m = 0 :=
id     └────┘                  └───┘   
src    └────┘                      └───┘     
typ    └────┘                  └───┘   
doc    └────┘                          └───┘
1043  ⟨λ (H : finset.sup (f.support) some ≤ n) m (Hm : n < (m : with_bot ℕ)), decidable.of_not_not $ λ H4,
id           └────────┘  └──────┘  └──┘                 └──────┘     └──────────────────┘     └┘
src          └────────┘   └──────┘  └──┘                     └──────┘     └──────────────────┘
typ          └────────┘  └──────┘  └──┘                 └──────┘     └──────────────────┘     └┘
doc          └────────┘
1044    have H1 : m ∉ f.support,
id                 └──────┘
src                  └──────┘
typ                └──────┘
1045      from λ H2, not_lt_of_ge ((finset.sup_le_iff.1 H) m H2 : ((m : with_bot ℕ) ≤ n)) Hm,
id              └┘  └──────────┘   └───────────────┘     └┘        └──────┘       └┘
src                 └──────────┘   └───────────────┘                  └──────┘   
typ             └┘  └──────────┘   └───────────────┘     └┘        └──────┘       └┘
1046    H1 $ (finsupp.mem_support_to_fun f m).2 H4,
id     └┘    └────────────────────────┘     └┘
src          └────────────────────────┘     
typ    └┘    └────────────────────────┘     └┘
1047  λ H, finset.sup_le $ λ b Hb, decidable.of_not_not $ λ Hn,
id       └───────────┘      └┘  └──────────────────┘     └┘
src       └───────────┘           └──────────────────┘
typ      └───────────┘      └┘  └──────────────────┘     └┘
1048    (finsupp.mem_support_to_fun f b).1 Hb $ H b $ lt_of_not_ge Hn⟩
id      └────────────────────────┘     └┘       └──────────┘ └┘
src     └────────────────────────┘                  └──────────┘
typ     └────────────────────────┘     └┘       └──────────┘ └┘
1049  
1050  theorem nat_degree_le_of_degree_le {p : polynomial α} {n : ℕ}
id                                           └────────┘        
src                                          └────────┘         
typ                                          └────────┘        
doc                                          └────────┘
1051    (H : degree p ≤ n) : nat_degree p ≤ n :=
id          └────┘       └────────┘   
src         └────┘         └────────┘   
typ         └────┘       └────────┘   
doc         └────┘          └────────┘
1052  show option.get_or_else (degree p) 0 ≤ n, from match degree p, H with
id        └────────────────┘  └────┘                   └────┘   
src       └────────────────┘  └────┘                     └────┘
typ       └────────────────┘  └────┘                   └────┘   
doc                           └────┘                      └────┘
1053  | none,     H := zero_le _
id     └──┘           └─────┘
src    └──┘           └─────┘
typ    └──┘           └─────┘
1054  | (some d), H := with_bot.coe_le_coe.1 H
id      └──┘         └─────────────────┘
src     └──┘          └─────────────────┘
typ     └──┘         └─────────────────┘
1055  end
1056  
1057  theorem leading_coeff_mul_X_pow {p : polynomial α} {n : ℕ} :
id                                        └────────┘        
src                                       └────────┘         
typ                                       └────────┘        
doc                                       └────────┘
1058    leading_coeff (p * X ^ n) = leading_coeff p :=
id     └───────────┘         └───────────┘ 
src    └───────────┘           └───────────┘
typ    └───────────┘         └───────────┘ 
doc    └───────────┘              └───────────┘
1059  decidable.by_cases
id   └────────────────┘
src  └────────────────┘
typ  └────────────────┘
1060    (assume H : leading_coeff p = 0, by rw [H, leading_coeff_eq_zero.1 H, zero_mul, leading_coeff_zero])
id                 └───────────┘               └───────────────────┘     └──────┘  └────────────────┘
src                └───────────┘          └──┘ └┘└───────────────────┘└─┘ └┘└──────┘└┘└────────────────┘
typ                └───────────┘         └──┘└┘└───────────────────┘└─┘└┘└──────┘└┘└────────────────┘
doc                └───────────┘           └──┘ └┘                     └─┘ └┘        └┘                  
txt                                        └──┘ └┘                     └─┘ └┘        └┘                  
par                                        └──┘ └┘                     └─┘ └┘        └┘                  
pid                                          └┘ └┘                     └─┘ └┘        └┘                  
st                                        └────┘└─────────────────────────┘└────────┘└──────────────────┘
1061    (assume H : leading_coeff p ≠ 0,
id                 └───────────┘  
src                └───────────┘   
typ                └───────────┘  
doc                └───────────┘
1062      by rw [leading_coeff_mul', leading_coeff_X_pow, mul_one];
id              └────────────────┘  └─────────────────┘  └─────┘
src         └──┘└────────────────┘└┘└─────────────────┘└┘└─────┘
typ         └──┘└────────────────┘└┘└─────────────────┘└┘└─────┘
doc         └──┘                  └┘                   └┘       
txt         └──┘                  └┘                   └┘       
par         └──┘                  └┘                   └┘       
pid           └┘                  └┘                   └┘       
st         └─────────────────────┘└───────────────────┘└───────┘└─
1063        rwa [leading_coeff_X_pow, mul_one])
id              └─────────────────┘  └─────┘
src        └───┘└─────────────────┘└┘└─────┘
typ        └───┘└─────────────────┘└┘└─────┘
doc        └───┘                   └┘       
txt        └───┘                   └┘       
par        └───┘                   └┘       
pid           └┘                   └┘       
st   ──────────┘└─────────────────┘└───────┘
1064  
1065  lemma monic_mul (hp : monic p) (hq : monic q) : monic (p * q) :=
id                         └───┘         └───┘     └───┘    
src                        └───┘          └───┘      └───┘    
typ                        └───┘         └───┘     └───┘    
doc                        └───┘          └───┘      └───┘
1066  if h0 : (0 : α) = 1 then by haveI := subsingleton_of_zero_eq_one _ h0;
id   └┘                                 └─────────────────────────┘   └┘
src  └┘                         └───────┘└─────────────────────────┘└─┘
typ  └┘                        └───────┘└─────────────────────────┘└─┘└┘
doc                              └───────┘└─────────────────────────┘└─┘
txt                              └───────┘                           └─┘
par                              └───────┘                           └─┘
pid                                   └─┘                           └─┘
st                              └───────────────────────────────────────────
1067    exact subsingleton.elim _ _
id           └───────────────┘
src    └────┘└───────────────┘└───┘
typ    └────┘└───────────────┘└───┘
doc    └────┘                 └───┘
txt    └────┘                 └───┘
par    └────┘                 └───┘
pid                          └──┘
st   ─────────────────────────────┘
1068  else
1069    have leading_coeff p * leading_coeff q ≠ 0, by simp [monic.def.1 hp, monic.def.1 hq, ne.symm h0],
id     └──┘ └───────────┘   └───────────┘               └───────┘   └┘  └───────┘   └┘  └─────┘ └┘
src         └───────────┘    └───────────┘          └────┘└───────┘└─┘  └┘└───────┘└─┘  └┘└─────┘  
typ    └──┘ └───────────┘   └───────────┘         └────┘└───────┘└─┘└┘└┘└───────┘└─┘└┘└┘└─────┘└┘
doc         └───────────┘     └───────────┘           └────┘         └─┘  └┘         └─┘  └┘         
txt                                                   └────┘         └─┘  └┘         └─┘  └┘         
par                                                   └────┘         └─┘  └┘         └─┘  └┘         
pid                                                                └─┘  └┘         └─┘  └┘         
st                                                   └────────────────────────────────────────────────┘
1070    by rw [monic.def, leading_coeff_mul' this, monic.def.1 hp, monic.def.1 hq, one_mul]
id            └───────┘  └────────────────┘ └──┘  └───────┘   └┘  └───────┘   └┘  └─────┘
src       └──┘└───────┘└┘└────────────────┘    └┘└───────┘└─┘  └┘└───────┘└─┘  └┘└─────┘└─
typ       └──┘└───────┘└┘└────────────────┘└──┘└┘└───────┘└─┘└┘└┘└───────┘└─┘└┘└┘└─────┘└─
doc       └──┘         └┘                      └┘         └─┘  └┘         └─┘  └┘       └─
txt       └──┘         └┘                      └┘         └─┘  └┘         └─┘  └┘       └─
par       └──┘         └┘                      └┘         └─┘  └┘         └─┘  └┘       └─
pid         └┘         └┘                      └┘         └─┘  └┘         └─┘  └┘       
st       └────────────┘└───────────────────────┘└──────────────┘└──────────────┘└───────┘
1071  
src  
typ  
doc  
txt  
par  
pid  
st   
1072  lemma monic_pow (hp : monic p) : ∀ (n : ℕ), monic (p ^ n)
id                         └───┘              └───┘    
src                        └───┘                └───┘    
typ                        └───┘              └───┘    
doc                        └───┘                 └───┘
1073  | 0     := monic_one
id              └───────┘
src             └───────┘
typ             └───────┘
1074  | (n+1) := monic_mul hp (monic_pow n)
id            └───────┘ └┘  └───────┘
src            └───────┘
typ           └───────┘ └┘  └───────┘
1075  
1076  lemma multiplicity_finite_of_degree_pos_of_monic (hp : (0 : with_bot ℕ) < degree p)
id                                                               └──────┘    └────┘ 
src                                                              └──────┘    └────┘
typ                                                              └──────┘    └────┘ 
doc                                                                            └────┘
1077    (hmp : monic p) (hq : q ≠ 0) : multiplicity.finite p q :=
id            └───┘                └─────────────────┘  
src           └───┘                  └─────────────────┘
typ           └───┘                └─────────────────┘  
doc           └───┘
1078  have zn0 : (0 : α) ≠ 1, from λ h, by haveI := subsingleton_of_zero_eq_one _ h;
id                                              └─────────────────────────┘   
src                                      └───────┘└─────────────────────────┘└─┘
typ                                    └───────┘└─────────────────────────┘└─┘
doc                                       └───────┘└─────────────────────────┘└─┘
txt                                       └───────┘                           └─┘
par                                       └───────┘                           └─┘
pid                                            └─┘                           └─┘
st                                       └──────────────────────────────────────────
1079    exact hq (subsingleton.elim _ _),
id           └┘  └───────────────┘
src    └────┘   └───────────────┘└───┘
typ    └────┘└┘ └───────────────┘└───┘
doc    └────┘                    └───┘
txt    └────┘                    └───┘
par    └────┘                    └───┘
pid                             └───┘
st   ─────────────────────────────────┘
1080  ⟨nat_degree q, λ ⟨r, hr⟩,
id    └────────┘     
src   └────────┘
typ   └────────┘     
doc   └────────┘
1081    have hp0 : p ≠ 0, from λ hp0, by simp [hp0] at hp; contradiction,
id                            └─┘           └─┘
src                                    └────┘   └─────┘  └───────────┘
typ                           └─┘     └────┘└─┘└─────┘  └───────────┘
doc                                     └────┘   └─────┘  └───────────┘
txt                                     └────┘   └─────┘  └───────────┘
par                                     └────┘   └─────┘  └───────────┘
pid                                            └───┘
st                                     └──────────────────────────────┘
1082    have hr0 : r ≠ 0, from λ hr0, by simp * at *,
id                             └─┘
src                                    └─────────┘
typ                            └─┘     └─────────┘
doc                                     └─────────┘
txt                                     └─────────┘
par                                     └─────────┘
pid                                         └──┘
st                                     └──────────┘
1083    have hpn1 : leading_coeff p ^ (nat_degree q + 1) = 1,
id                 └───────────┘    └────────┘      
src                └───────────┘     └────────┘       
typ                └───────────┘    └────────┘      
doc                └───────────┘      └────────┘
1084      by simp [show _ = _, from hmp],
id                                └─┘
src         └────┘    └─┘└───────┘   
typ         └────┘    └─┘└───────┘└─┘
doc         └────┘    └─┘ └───────┘   
txt         └────┘    └─┘ └───────┘   
par         └────┘    └─┘ └───────┘   
pid                 └─┘ └───────┘   
st         └──────────────────────────┘
1085    have hpn0' : leading_coeff p ^ (nat_degree q + 1) ≠ 0,
id                  └───────────┘    └────────┘      
src                 └───────────┘     └────────┘       
typ                 └───────────┘    └────────┘      
doc                 └───────────┘      └────────┘
1086      from hpn1.symm ▸ zn0.symm,
id            └──┘└───┘  └─┘└───┘
src               └───┘     └───┘
typ           └──┘└───┘  └─┘└───┘
1087    have hpnr0 : leading_coeff (p ^ (nat_degree q + 1)) * leading_coeff r ≠ 0,
id                  └───────────┘     └────────┘        └───────────┘   
src                 └───────────┘      └────────┘         └───────────┘   
typ                 └───────────┘     └────────┘        └───────────┘   
doc                 └───────────┘       └────────┘           └───────────┘
1088      by simp only [leading_coeff_pow' hpn0', leading_coeff_eq_zero, hpn1,
id                     └────────────────┘ └───┘  └───────────────────┘  └──┘
src         └─────────┘└────────────────┘     └┘└───────────────────┘└┘    └─
typ         └─────────┘└────────────────┘└───┘└┘└───────────────────┘└┘└──┘└─
doc         └─────────┘                       └┘                     └┘    └─
txt         └─────────┘                       └┘                     └┘    └─
par         └─────────┘                       └┘                     └┘    └─
pid             └──┘└┘                       └┘                     └┘    └─
st         └──────────────────────────────────────────────────────────────────
1089        one_pow, one_mul, ne.def, hr0]; simp,
id         └─────┘  └─────┘  └────┘  └─┘
src  ─────┘└─────┘└┘└─────┘└┘└────┘└┘     └──┘
typ  ─────┘└─────┘└┘└─────┘└┘└────┘└┘└─┘  └──┘
doc  ─────┘       └┘       └┘      └┘     └──┘
txt  ─────┘       └┘       └┘      └┘     └──┘
par  ─────┘       └┘       └┘      └┘     └──┘
pid  ─────┘       └┘       └┘      └┘   
st   ─────────────────────────────────────────┘
1090    have hpn0 : p ^ (nat_degree q + 1) ≠ 0,
id                    └────────┘      
src                    └────────┘       
typ                   └────────┘      
doc                     └────────┘
1091      from mt leading_coeff_eq_zero.2 $
id            └┘ └───────────────────┘
src           └┘ └───────────────────┘
typ           └┘ └───────────────────┘
1092        by rw [leading_coeff_pow' hpn0', show _ = _, from hmp, one_pow]; exact zn0.symm,
id                └────────────────┘ └───┘                  └─┘  └─────┘         └──────┘
src           └──┘└────────────────┘     └┘    └─┘ └───────┘   └┘└─────┘  └────┘└──────┘
typ           └──┘└────────────────┘└───┘└┘    └─┘└───────┘└─┘└┘└─────┘  └────┘└──────┘
doc           └──┘                       └┘    └─┘ └───────┘   └┘         └────┘
txt           └──┘                       └┘    └─┘ └───────┘   └┘         └────┘
par           └──┘                       └┘    └─┘ └───────┘   └┘         └────┘
pid             └┘                       └┘    └─┘ └───────┘   └┘              
st           └───────────────────────────┘└────────────────────┘└───────┘└──────────────┘
1093    have hnp : 0 < nat_degree p,
id                   └────────┘ 
src                  └────────┘
typ                  └────────┘ 
doc                   └────────┘
1094      by rw [← with_bot.coe_lt_coe, ← degree_eq_nat_degree hp0];
id                └─────────────────┘    └──────────────────┘ └─┘
src         └────┘└─────────────────┘└──┘└──────────────────┘   
typ         └────┘└─────────────────┘└──┘└──────────────────┘└─┘
doc         └────┘                   └──┘                       
txt         └────┘                   └──┘                       
par         └────┘                   └──┘                       
pid           └──┘                   └──┘                       
st         └────────────────────────┘└──────────────────────────┘└─
1095      exact hp,
id             └┘
src      └────┘
typ      └────┘└┘
doc      └────┘
txt      └────┘
par      └────┘
pid           
st   ───────────┘
1096    begin
st     └─────
1097      have := congr_arg nat_degree hr,
id               └───────┘ └────────┘ └┘
src      └──────┘└───────┘└────────┘
typ      └──────┘└───────┘└────────┘└┘
doc      └──────┘         └────────┘
txt      └──────┘                   
par      └──────┘                   
pid      └───┘└─┘                   
st   ──────────────────────────────────┘└─
1098      rw [nat_degree_mul_eq' hpnr0,  nat_degree_pow_eq' hpn0', add_mul, add_assoc] at this,
id           └────────────────┘ └───┘   └────────────────┘ └───┘  └─────┘  └───────┘
src      └──┘└────────────────┘     └─┘└────────────────┘     └┘└─────┘└┘└───────┘└───────┘
typ      └──┘└────────────────┘└───┘└─┘└────────────────┘└───┘└┘└─────┘└┘└───────┘└───────┘
doc      └──┘                       └─┘                       └┘       └┘         └───────┘
txt      └──┘                       └─┘                       └┘       └┘         └───────┘
par      └──┘                       └─┘                       └┘       └┘         └───────┘
pid        └┘                       └─┘                       └┘       └┘         └──────┘
st   ───────────────────────────────┘└─────────────────────────┘└───────┘└─────────┘└──────┘└─
1099      exact ne_of_lt (lt_add_of_le_of_pos (le_mul_of_one_le_right' (nat.zero_le _) hnp)
id             └──────┘  └─────────────────┘  └─────────────────────┘                 └─┘
src      └────┘└──────┘ └─────────────────┘ └─────────────────────┘            └──┘   └─
typ      └────┘└──────┘ └─────────────────┘ └─────────────────────┘            └──┘└─┘└─
doc      └────┘                                                                └──┘   └─
txt      └────┘                                                                └──┘   └─
par      └────┘                                                                └──┘   └─
pid                                                                           └──┘   └─
st   ──────────────────────────────────────────────────────────────────────────────────────
1100        (add_pos_of_pos_of_nonneg (by rwa one_mul) (nat.zero_le _))) this
id          └──────────────────────┘         └─────┘   └─────────┘      └──┘
src  ─────┘ └──────────────────────┘   └──┘└─────┘└┘ └─────────┘└────┘    
typ  ─────┘ └──────────────────────┘   └──┘└─────┘└┘ └─────────┘└────┘└──┘
doc  ─────┘                            └──┘       └┘            └────┘    
txt  ─────┘                            └──┘       └┘            └────┘    
par  ─────┘                            └──┘       └┘            └────┘    
pid  ─────┘                            └───┘       └┘            └────┘    
st   ──────────────────────────────────┘└──────────┘└────────────────────────
1101    end⟩
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘└─┘
1102  
1103  end comm_semiring
1104  
1105  section nonzero_comm_semiring
1106  variables [nonzero_comm_semiring α] {p q : polynomial α}
id              └───────────────────┘           └────────┘
src             └───────────────────┘           └────────┘
typ             └───────────────────┘           └────────┘
doc             └───────────────────┘           └────────┘
1107  
1108  instance : nonzero_comm_semiring (polynomial α) :=
id              └───────────────────┘  └────────┘ 
src             └───────────────────┘  └────────┘
typ             └───────────────────┘  └────────┘ 
doc             └───────────────────┘  └────────┘
1109  { zero_ne_one := λ (h : (0 : polynomial α) = 1),
id                                └────────┘   
src                               └────────┘    
typ                               └────────┘   
doc                               └────────┘
1110      @zero_ne_one α _ $
id        └─────────┘ 
src       └─────────┘
typ       └─────────┘ 
1111      calc (0 : α) = eval 0 0 : eval_zero.symm
id                     └──┘       └───────┘└───┘
src                     └──┘       └───────┘└───┘
typ                    └──┘       └───────┘└───┘
doc                     └──┘
1112        ... = eval 0 1 : congr_arg _ h
id               └──┘       └───────┘   
src              └──┘       └───────┘
typ              └──┘       └───────┘   
doc              └──┘
1113        ... = 1 : eval_C,
id                   └────┘
src                  └────┘
typ                  └────┘
1114    ..polynomial.comm_semiring }
id       └──────────────────────┘
src      └──────────────────────┘
typ      └──────────────────────┘
1115  
1116  @[simp] lemma degree_one : degree (1 : polynomial α) = (0 : with_bot ℕ) :=
id                              └────┘      └────────┘         └──────┘ 
src                             └────┘      └────────┘          └──────┘ 
typ                             └────┘      └────────┘         └──────┘ 
doc    └──┘                     └────┘      └────────┘
1117  degree_C (show (1 : α) ≠ 0, from zero_ne_one.symm)
id   └──────┘                       └─────────┘└───┘
src  └──────┘                        └─────────┘└───┘
typ  └──────┘                       └─────────┘└───┘
1118  
1119  @[simp] lemma degree_X : degree (X : polynomial α) = 1 :=
id                            └────┘     └────────┘   
src                           └────┘     └────────┘    
typ                           └────┘     └────────┘   
doc    └──┘                   └────┘     └────────┘
1120  begin
st   └─────
1121    unfold X degree single finsupp.support,
src    └────────────────────────────────────┘
typ    └────────────────────────────────────┘
doc    └────────────────────────────────────┘
txt    └────────────────────────────────────┘
par    └────────────────────────────────────┘
pid          └──────────────────────────────┘
st   ───────────────────────────────────────┘└─
1122    rw if_neg (zero_ne_one).symm,
id        └────┘  └─────────┘
src    └─┘└────┘ └─────────┘└────┘
typ    └─┘└────┘ └─────────┘└────┘
doc    └─┘                  └────┘
txt    └─┘                  └────┘
par    └─┘                  └────┘
pid                        └───┘
st   ─────────────────────────────┘└─
1123    refl
src    └───┘
typ    └───┘
doc    └───┘
txt    └───┘
par    └───┘
pid        
st   ──────┘
1124  end
st   └─┘
1125  
1126  lemma X_ne_zero : (X : polynomial α) ≠ 0 :=
id                         └────────┘   
src                        └────────┘    
typ                        └────────┘   
doc                        └────────┘
1127  mt (congr_arg (λ p, coeff p 1)) (by simp)
id   └┘  └───────┘      └───┘ 
src  └┘  └───────┘       └───┘           └──┘
typ  └┘  └───────┘      └───┘          └──┘
doc                      └───┘           └──┘
txt                                      └──┘
par                                      └──┘
st                                      └───┘
1128  
1129  @[simp] lemma degree_X_pow : ∀ (n : ℕ), degree ((X : polynomial α) ^ n) = n
id                                         └────┘      └────────┘       
src                                         └────┘      └────────┘        
typ                                        └────┘      └────────┘       
doc    └──┘                                  └────┘      └────────┘
1130  | 0 := by simp only [pow_zero, degree_one]; refl
id                        └──────┘  └────────┘
src            └─────────┘└──────┘└┘└────────┘  └───┘
typ            └─────────┘└──────┘└┘└────────┘  └───┘
doc            └─────────┘        └┘            └───┘
txt            └─────────┘        └┘            └───┘
par            └─────────┘        └┘            └───┘
pid                └──┘└┘        └┘                
st            └──────────────────────────────────────┘
1131  | (n+1) :=
id      
src      
typ     
1132  have h : leading_coeff (X : polynomial α) * leading_coeff (X ^ n) ≠ 0,
id            └───────────┘     └────────┘    └───────────┘       
src           └───────────┘     └────────┘     └───────────┘       
typ           └───────────┘     └────────┘    └───────────┘       
doc           └───────────┘     └────────┘      └───────────┘  
1133    by rw [leading_coeff_X, leading_coeff_X_pow n, one_mul];
id            └─────────────┘  └─────────────────┘   └─────┘
src       └──┘└─────────────┘└┘└─────────────────┘ └┘└─────┘
typ       └──┘└─────────────┘└┘└─────────────────┘└┘└─────┘
doc       └──┘               └┘                    └┘       
txt       └──┘               └┘                    └┘       
par       └──┘               └┘                    └┘       
pid         └┘               └┘                    └┘       
st       └──────────────────┘└─────────────────────┘└───────┘└─
1134      exact zero_ne_one.symm,
id             └──────────────┘
src      └────┘└──────────────┘
typ      └────┘└──────────────┘
doc      └────┘
txt      └────┘
par      └────┘
pid           
st   ─────────────────────────┘
1135  by rw [pow_succ, degree_mul_eq' h, degree_X, degree_X_pow, add_comm]; refl
id          └──────┘  └────────────┘   └──────┘  └──────────┘  └──────┘
src     └──┘└──────┘└┘└────────────┘ └┘└──────┘└┘            └┘└──────┘  └────
typ     └──┘└──────┘└┘└────────────┘└┘└──────┘└┘└──────────┘└┘└──────┘  └────
doc     └──┘        └┘               └┘        └┘            └┘          └────
txt     └──┘        └┘               └┘        └┘            └┘          └────
par     └──┘        └┘               └┘        └┘            └┘          └────
pid       └┘        └┘               └┘        └┘            └┘              
st     └───────────┘└────────────────┘└────────┘└────────────┘└────────┘└──────
1136  
src  
typ  
doc  
txt  
par  
pid  
st   
1137  @[simp] lemma not_monic_zero : ¬monic (0 : polynomial α) :=
id                                  └───┘      └────────┘ 
src                                 └───┘      └────────┘
typ                                 └───┘      └────────┘ 
doc    └──┘                          └───┘      └────────┘
1138  by simpa only [monic, leading_coeff_zero] using zero_ne_one
id                  └───┘  └────────────────┘        └─────────┘
src     └──────────┘└───┘└┘└────────────────┘└──────┘└─────────┘
typ     └──────────┘└───┘└┘└────────────────┘└──────┘└─────────┘
doc     └──────────┘└───┘└┘                  └──────┘           
txt     └──────────┘     └┘                  └──────┘           
par     └──────────┘     └┘                  └──────┘           
pid          └──┘└┘     └┘                  └────┘           
st     └─────────────────────────────────────────────────────────
1139  
src  
typ  
doc  
txt  
par  
pid  
st   
1140  lemma ne_zero_of_monic (h : monic p) : p ≠ 0 :=
id                               └───┘      
src                              └───┘        
typ                              └───┘      
doc                              └───┘
1141  λ h₁, @not_monic_zero α _ (h₁ ▸ h)
id     └┘   └────────────┘     └┘  
src         └────────────┘         
typ    └┘   └────────────┘     └┘  
1142  
1143  end nonzero_comm_semiring
1144  
1145  section comm_semiring
1146  variables [comm_semiring α] {p q : polynomial α}
id              └───────────┘           └────────┘
src             └───────────┘           └────────┘
typ             └───────────┘           └────────┘
doc                                     └────────┘
1147  
1148  /-- `dix_X p` return a polynomial `q` such that `q * X + C (p.coeff 0) = p`.
1149    It can be used in a semiring where the usual division algorithm is not possible -/
1150  def div_X (p : polynomial α) : polynomial α :=
id                  └────────┘     └────────┘ 
src                 └────────┘      └────────┘
typ                 └────────┘     └────────┘ 
doc                 └────────┘      └────────┘
1151  { to_fun := λ n, p.coeff (n + 1),
id                   └────┘   
src                    └────┘    
typ                  └────┘   
doc                    └────┘
1152    support := ⟨(p.support.filter (> 0)).1.map (λ n, n - 1),
id                  └──────┘└─────┘       └─┘        
src                  └──────┘└─────┘       └─┘          
typ                 └──────┘└─────┘       └─┘        
doc                          └─────┘         └─┘
1153      multiset.nodup_map_on begin
id       └───────────────────┘
src      └───────────────────┘
typ      └───────────────────┘
st                             └─────
1154          simp only [finset.mem_def.symm, finset.mem_erase, finset.mem_filter],
id                                           └──────────────┘  └───────────────┘
src          └─────────┘                   └┘└──────────────┘└┘└───────────────┘
typ          └─────────┘└─────────────────┘└┘└──────────────┘└┘└───────────────┘
doc          └─────────┘                   └┘                └┘                 
txt          └─────────┘                   └┘                └┘                 
par          └─────────┘                   └┘                └┘                 
pid              └──┘└┘                   └┘                └┘                 
st   ───────────────────────────────────────────────────────────────────────────┘└─
1155          assume x hx y hy hxy,
src          └──────────────────┘
typ          └──────────────────┘
doc          └──────────────────┘
txt          └──────────────────┘
par          └──────────────────┘
pid          └──────────────────┘
st   ───────────────────────────┘└─
1156          rwa [← @add_right_cancel_iff _ _ 1, nat.sub_add_cancel hx.2,
id                   └──────────────────┘        └────────────────┘ └┘
src          └─────┘ └──────────────────┘└──────┘└────────────────┘  └───
typ          └─────┘ └──────────────────┘└──────┘└────────────────┘└┘└───
doc          └─────┘                     └──────┘                    └───
txt          └─────┘                     └──────┘                    └───
par          └─────┘                     └──────┘                    └───
pid             └──┘                     └──────┘                    └───
st   ────────────────────────────────────────┘└──────────────────────┘└───
1157            nat.sub_add_cancel hy.2] at hxy
id             └────────────────┘ └┘
src  ─────────┘└────────────────┘  └──────────
typ  ─────────┘└────────────────┘└┘└──────────
doc  ─────────┘                    └──────────
txt  ─────────┘                    └──────────
par  ─────────┘                    └──────────
pid  ─────────┘                    └─┘└─────┘
st   ──────────────────────────────┘└─┘└───────
1158        end
src  ─────┘
typ  ─────┘
doc  ─────┘
txt  ─────┘
par  ─────┘
pid  ─────┘
st   ─────┘└─┘
1159        (p.support.filter (> 0)).2⟩,
id          └──────┘└─────┘      
src          └──────┘└─────┘      
typ         └──────┘└─────┘      
doc                  └─────┘
1160    mem_support_to_fun := λ n,
id                             
typ                            
1161      suffices (∃ (a : ℕ), (¬coeff p a = 0 ∧ a > 0) ∧ a - 1 = n) ↔
id                          └───┘                    
src                         └───┘                         
typ                         └───┘                    
doc                             └───┘
1162        ¬coeff p (n + 1) = 0,
id         └───┘        
src        └───┘          
typ        └───┘        
doc         └───┘
1163      by simpa [finset.mem_def.symm, apply_eq_coeff],
id                                      └────────────┘
src         └─────┘                   └┘└────────────┘
typ         └─────┘└─────────────────┘└┘└────────────┘
doc         └─────┘                   └┘              
txt         └─────┘                   └┘              
par         └─────┘                   └┘              
pid                                 └┘              
st         └──────────────────────────────────────────┘
1164      ⟨λ ⟨a, ha⟩, by rw [← ha.2, nat.sub_add_cancel ha.1.2]; exact ha.1.1,
id                           └┘    └────────────────┘ └┘             └┘
src                     └────┘  └──┘└────────────────┘  └───┘  └────┘  └──┘
typ                    └────┘└┘└──┘└────────────────┘└┘└───┘  └────┘└┘└──┘
doc                     └────┘  └──┘                    └───┘  └────┘  └──┘
txt                     └────┘  └──┘                    └───┘  └────┘  └──┘
par                     └────┘  └──┘                    └───┘  └────┘  └──┘
pid                       └──┘  └──┘                    └───┘         └┘└┘
st                     └───────┘└─────────────────────────┘└─┘└────────────┘
1165        λ h, ⟨n + 1, ⟨h, nat.succ_pos _⟩, nat.succ_sub_one _⟩⟩ }
id                      └──────────┘     └──────────────┘
src                        └──────────┘     └──────────────┘
typ                     └──────────┘     └──────────────┘
1166  
1167  lemma div_X_mul_X_add (p : polynomial α) : div_X p * X + C (p.coeff 0) = p :=
id                              └────────┘     └───┘       └────┘     
src                             └────────┘      └───┘         └────┘    
typ                             └────────┘     └───┘       └────┘     
doc                             └────────┘      └───┘           └────┘
1168  ext $ λ n,
id   └─┘     
src  └─┘
typ  └─┘     
1169    nat.cases_on n
id     └──────────┘ 
src    └──────────┘
typ    └──────────┘ 
1170     (by simp)
src         └──┘
typ         └──┘
doc         └──┘
txt         └──┘
par         └──┘
st         └───┘
1171     (by simp [coeff_C, nat.succ_ne_zero, coeff_mul_X, div_X])
id                └─────┘  └──────────────┘  └─────────┘  └───┘
src         └────┘└─────┘└┘└──────────────┘└┘└─────────┘└┘└───┘
typ         └────┘└─────┘└┘└──────────────┘└┘└─────────┘└┘└───┘
doc         └────┘       └┘                └┘           └┘└───┘
txt         └────┘       └┘                └┘           └┘     
par         └────┘       └┘                └┘           └┘     
pid                    └┘                └┘           └┘     
st         └───────────────────────────────────────────────────┘
1172  
1173  @[simp] lemma div_X_C (a : α) : div_X (C a) = 0 :=
id                                  └───┘     
src                                  └───┘      
typ                                 └───┘     
doc    └──┘                          └───┘  
1174  ext $ λ n, by cases n; simp [div_X, coeff_C]; simp [coeff]
id   └─┘                        └───┘  └─────┘
src  └─┘           └────┘   └────┘└───┘└┘└─────┘  └────┘     └─
typ  └─┘          └────┘  └────┘└───┘└┘└─────┘  └────┘     └─
doc                └────┘   └────┘└───┘└┘         └────┘     └─
txt                └────┘   └────┘     └┘         └────┘     └─
par                └────┘   └────┘     └┘         └────┘     └─
pid                                 └┘                  
st                └─────────────────────────────────────────────
1175  
src  
typ  
doc  
txt  
par  
pid  
st   
1176  lemma div_X_eq_zero_iff : div_X p = 0 ↔ p = C (p.coeff 0) :=
id                             └───┘          └────┘
src                            └───┘             └────┘
typ                            └───┘          └────┘
doc                            └───┘                └────┘
1177  ⟨λ h, by simpa [eq_comm, h] using div_X_mul_X_add p,
id                  └─────┘          └─────────────┘ 
src           └─────┘└─────┘└┘ └──────┘└─────────────┘
typ          └─────┘└─────┘└┘└──────┘└─────────────┘
doc           └─────┘       └┘ └──────┘               
txt           └─────┘       └┘ └──────┘               
par           └─────┘       └┘ └──────┘               
pid                       └┘ └────┘               
st           └─────────────────────────────────────────┘
1178    λ h, by rw [h, div_X_C]⟩
id                  └─────┘
src            └──┘ └┘└─────┘
typ           └──┘└┘└─────┘
doc            └──┘ └┘       
txt            └──┘ └┘       
par            └──┘ └┘       
pid              └┘ └┘       
st            └────┘└───────┘
1179  
1180  lemma div_X_add : div_X (p + q) = div_X p + div_X q :=
id                     └───┘       └───┘   └───┘ 
src                    └───┘         └───┘    └───┘
typ                    └───┘       └───┘   └───┘ 
doc                    └───┘           └───┘     └───┘
1181  ext $ by simp [div_X]
id   └─┘            └───┘
src  └─┘      └────┘└───┘└─
typ  └─┘      └────┘└───┘└─
doc           └────┘└───┘└─
txt           └────┘     └─
par           └────┘     └─
pid                    
st           └─────────────
1182  
src  
typ  
doc  
txt  
par  
pid  
st   
1183  def nonzero_comm_semiring.of_polynomial_ne (h : p ≠ q) : nonzero_comm_semiring α :=
id                                                         └───────────────────┘ 
src                                                          └───────────────────┘
typ                                                        └───────────────────┘ 
doc                                                           └───────────────────┘
1184  { zero_ne_one := λ h01 : 0 = 1, h $
id                                  
src                             
typ                                 
1185      by rw [← mul_one p, ← mul_one q, ← C_1, ← h01, C_0, mul_zero, mul_zero],
id                └─────┘     └─────┘     └─┘    └─┘  └─┘  └──────┘  └──────┘
src         └────┘└─────┘ └──┘└─────┘ └──┘└─┘└──┘   └┘└─┘└┘└──────┘└┘└──────┘
typ         └────┘└─────┘└──┘└─────┘└──┘└─┘└──┘└─┘└┘└─┘└┘└──────┘└┘└──────┘
doc         └────┘        └──┘        └──┘   └──┘   └┘   └┘        └┘        
txt         └────┘        └──┘        └──┘   └──┘   └┘   └┘        └┘        
par         └────┘        └──┘        └──┘   └──┘   └┘   └┘        └┘        
pid           └──┘        └──┘        └──┘   └──┘   └┘   └┘        └┘        
st         └──────────────┘└───────────┘└─────┘└─────┘└───┘└────────┘└────────┘
1186    ..show comm_semiring α, by apply_instance }
id            └───────────┘ 
src           └───────────┘       └─────────────┘
typ           └───────────┘      └─────────────┘
doc                               └─────────────┘
txt                               └─────────────┘
par                               └─────────────┘
pid                                             
st                               └──────────────┘
1187  
1188  lemma degree_lt_degree_mul_X (hp : p ≠ 0) : p.degree < (p * X).degree :=
id                                             └─────┘      └────┘
src                                              └─────┘       └────┘
typ                                            └─────┘      └────┘
doc                                               └─────┘         └────┘
1189  by letI := nonzero_comm_semiring.of_polynomial_ne hp; exact
id              └────────────────────────────────────┘ └┘
src     └──────┘└────────────────────────────────────┘    └────┘
typ     └──────┘└────────────────────────────────────┘└┘  └────┘
doc     └──────┘                                          └────┘
txt     └──────┘                                          └────┘
par     └──────┘                                          └────┘
pid         └─┘                                               
st     └─────────────────────────────────────────────────────────
1190  have leading_coeff p * leading_coeff X ≠ 0, by simpa,
id                        └───────────┘  
src      └─────────────┘ └───────────┘└─────┘└───┘└┘
typ      └─────────────┘└───────────┘└─────┘└───┘└┘
doc      └─────────────┘  └───────────┘ └─────┘└───┘└┘
txt      └─────────────┘                 └─────┘└───┘└┘
par      └─────────────┘                 └─────┘└───┘└┘
pid      └─────────────┘                 └────────────┘
st   ─────────────────────────────────────────────┘└────┘└─
1191  by erw [degree_mul_eq' this, degree_eq_nat_degree hp,
id           └────────────┘ └──┘  └──────────────────┘ └┘
src    └───┘└────────────┘    └┘└──────────────────┘  └─
typ    └───┘└────────────┘└──┘└┘└──────────────────┘└┘└─
doc    └───┘                  └┘                      └─
txt    └───┘                  └┘                      └─
par    └───┘                  └┘                      └─
pid    └────┘                  └┘                      └─
st   ─┘└───────────────────────┘└───────────────────────┘└─
1192      degree_X, ← with_bot.coe_one, ← with_bot.coe_add, with_bot.coe_lt_coe];
id       └──────┘    └──────────────┘    └──────────────┘  └─────────────────┘
src  ───┘└──────┘└──┘└──────────────┘└──┘└──────────────┘└┘└─────────────────┘└─
typ  ───┘└──────┘└──┘└──────────────┘└──┘└──────────────┘└┘└─────────────────┘└─
doc  ───┘        └──┘                └──┘                └┘                   └─
txt  ───┘        └──┘                └──┘                └┘                   └─
par  ───┘        └──┘                └──┘                └┘                   └─
pid  ───┘        └──┘                └──┘                └┘                   └──
st   ───────────┘└──────────────────┘└──────────────────┘└───────────────────┘└─
1193    exact nat.lt_succ_self _
id           └──────────────┘
src  ───────┘└──────────────┘└──
typ  ───────┘└──────────────┘└──
doc  ───────┘                └──
txt  ───────┘                └──
par  ───────┘                └──
pid  ───────┘                └──
st   ───────────────────────────
1194  
src  
typ  
doc  
txt  
par  
pid  
st   
1195  lemma degree_div_X_lt (hp0 : p ≠ 0) : (div_X p).degree < p.degree :=
id                                        └───┘  └────┘   └─────┘
src                                        └───┘   └────┘    └─────┘
typ                                       └───┘  └────┘   └─────┘
doc                                         └───┘   └────┘     └─────┘
1196  by letI := nonzero_comm_semiring.of_polynomial_ne hp0; exact
id              └────────────────────────────────────┘ └─┘
src     └──────┘└────────────────────────────────────┘     └────┘
typ     └──────┘└────────────────────────────────────┘└─┘  └────┘
doc     └──────┘                                           └────┘
txt     └──────┘                                           └────┘
par     └──────┘                                           └────┘
pid         └─┘                                                
st     └──────────────────────────────────────────────────────────
1197  calc (div_X p).degree < (div_X p * X + C (p.coeff 0)).degree :
id                                       
src             └───────┘                  └─────────────
typ             └───────┘                  └─────────────
doc             └───────┘                    └─────────────
txt             └───────┘                    └─────────────
par             └───────┘                    └─────────────
pid             └───────┘                    └─────────────
st   ───────────────────────────────────────────────────────────────
1198    if h : degree p ≤ 0
id     └┘              
src  ─┘└┘└───┘       └──
typ  ─┘└┘└───┘       └──
doc  ─┘  └───┘        └──
txt  ─┘  └───┘        └──
par  ─┘  └───┘        └──
pid  ─┘  └───┘        └──
st   ──────────────────────
1199    then begin
src  ──────┘     
typ  ──────┘     
doc  ──────┘     
txt  ──────┘     
par  ──────┘     
pid  ──────┘     
st   ──────┘└─────
1200        have h' : C (p.coeff 0) ≠ 0, by rwa [← eq_C_of_degree_le_zero h],
id                     └─────┘                   └────────────────────┘ 
src  ─────┘└────────┘ └─────┘└──┘ └┘└───┘└─────┘└────────────────────┘ └─
typ  ─────┘└────────┘ └─────┘└──┘ └┘└───┘└─────┘└────────────────────┘└─
doc  ─────┘└────────┘ └─────┘└──┘ └┘└───┘└─────┘                       └─
txt  ─────┘└────────┘         └──┘ └┘└───┘└─────┘                       └─
par  ─────┘└────────┘         └──┘ └┘└───┘└─────┘                       └─
pid  ───────────────┘         └──┘ └────────────┘                       └──
st   ────────────────────────────────┘          └────────────────────────┘└─
1201        rw [eq_C_of_degree_le_zero h, div_X_C, degree_zero, zero_mul, zero_add],
id             └────────────────────┘   └─────┘  └─────────┘  └──────┘  └──────┘
src  ─────┘└──┘└────────────────────┘ └┘└─────┘└┘└─────────┘└┘└──────┘└┘└──────┘└─
typ  ─────┘└──┘└────────────────────┘└┘└─────┘└┘└─────────┘└┘└──────┘└┘└──────┘└─
doc  ─────┘└──┘                       └┘       └┘           └┘        └┘        └─
txt  ─────┘└──┘                       └┘       └┘           └┘        └┘        └─
par  ─────┘└──┘                       └┘       └┘           └┘        └┘        └─
pid  ─────────┘                       └┘       └┘           └┘        └┘        └──
st   ─────────────────────────────────┘└───────┘└───────────┘└────────┘└────────┘└──
1202        exact lt_of_le_of_ne lattice.bot_le (ne.symm (mt degree_eq_bot.1 $
id               └────────────┘ └────────────┘  └─────┘  └┘ └───────────┘
src  ───────────┘└────────────┘└────────────┘ └─────┘ └┘└───────────┘└─┘ 
typ  ───────────┘└────────────┘└────────────┘ └─────┘ └┘└───────────┘└─┘ 
doc  ───────────┘                                                    └─┘ 
txt  ───────────┘                                                    └─┘ 
par  ───────────┘                                                    └─┘ 
pid  ───────────┘                                                    └─┘ 
st   ─────────────────────────────────────────────────────────────────────────
1203          by simp [h'])),
id                    └┘
src  ───────┘  └────┘  └───
typ  ───────┘  └────┘└┘└───
doc  ───────┘  └────┘  └───
txt  ───────┘  └────┘  └───
par  ───────┘  └────┘  └───
pid  ───────┘  └─────┘  └────
st   ─────────┘└────────┘└┘└─
1204      end
src  ────────
typ  ────────
doc  ────────
txt  ────────
par  ────────
pid  ────────
st   ──────┘
1205    else
src  ───────
typ  ───────
doc  ───────
txt  ───────
par  ───────
pid  ───────
st   ───────
1206      have hXp0 : div_X p ≠ 0,
id       └──┘                
src  ───┘    └──────┘      └───
typ  ───┘└──┘└──────┘      └───
doc  ───┘    └──────┘       └───
txt  ───┘    └──────┘       └───
par  ───┘    └──────┘       └───
pid  ───┘    └──────┘       └───
st   ─────────────────────────────
1207        by simpa [div_X_eq_zero_iff, -not_le, degree_le_zero_iff] using h,
id                   └───────────────┘           └────────────────┘        
src  ────────┘└─────┘└───────────────┘└─────────┘└────────────────┘└──────┘ └─
typ  ────────┘└─────┘└───────────────┘└─────────┘└────────────────┘└──────┘└─
doc  ────────┘└─────┘                 └─────────┘                  └──────┘ └─
txt  ────────┘└─────┘                 └─────────┘                  └──────┘ └─
par  ────────┘└─────┘                 └─────────┘                  └──────┘ └─
pid  ───────────────┘                 └─────────┘                  └──────┘ └─
st   ───────┘└─────────────────────────────────────────────────────────────┘└─
1208      have leading_coeff (div_X p) * leading_coeff X ≠ 0, by simpa,
id                                      └───────────┘
src  ───┘    └─────────────┘       └┘ └───────────┘  └─────┘└───┘└─
typ  ───┘    └─────────────┘       └┘ └───────────┘  └─────┘└───┘└─
doc  ───┘    └─────────────┘       └┘ └───────────┘  └─────┘└───┘└─
txt  ───┘    └─────────────┘       └┘                └─────┘└───┘└─
par  ───┘    └─────────────┘       └┘                └─────┘└───┘└─
pid  ───┘    └─────────────┘       └┘                └─────────────
st   ─────────────────────────────────────────────────────────┘└────┘└─
1209      have degree (C (p.coeff 0)) < degree (div_X p * X),
src  ───┘    └──────┘          └───┘                └──
typ  ───┘    └──────┘          └───┘                └──
doc  ───┘    └──────┘          └───┘                └──
txt  ───┘    └──────┘          └───┘                └──
par  ───┘    └──────┘          └───┘                └──
pid  ───┘    └──────┘          └───┘                └──
st   ────────────────────────────────────────────────────────
1210        from calc degree (C (p.coeff 0)) ≤ 0 : degree_C_le
id                             └─────┘           └─────────┘
src  ──────────┘            └─────┘└───┘ └───┘└─────────┘
typ  ──────────┘            └─────┘└───┘ └───┘└─────────┘
doc  ──────────┘            └─────┘└───┘ └───┘           
txt  ──────────┘                    └───┘ └───┘           
par  ──────────┘                    └───┘ └───┘           
pid  ──────────┘                    └───┘ └───┘           
st   ─────────────────────────────────────────────────────────
1211           ... < 1 : dec_trivial
id                      └─────────┘
src  ────────────┘ └───┘└─────────┘
typ  ────────────┘ └───┘└─────────┘
doc  ────────────┘ └───┘└─────────┘
txt  ────────────┘ └───┘           
par  ────────────┘ └───┘           
pid  ────────────┘ └───┘           
st   ───────────────────────────────
1212           ... = degree (X : polynomial α) : degree_X.symm
id                              └────────┘     └───────────┘
src  ────────────┘         └─┘└────────┘ └──┘└───────────┘
typ  ────────────┘         └─┘└────────┘└──┘└───────────┘
doc  ────────────┘         └─┘└────────┘ └──┘             
txt  ────────────┘         └─┘           └──┘             
par  ────────────┘         └─┘           └──┘             
pid  ────────────┘         └─┘           └──┘             
st   ─────────────────────────────────────────────────────────
1213           ... ≤ degree (div_X p * X) :
id                  └────┘  └───┘    
src  ────────────┘ └────┘ └───┘  └───
typ  ────────────┘ └────┘ └───┘ └───
doc  ────────────┘ └────┘ └───┘  └───
txt  ────────────┘                └───
par  ────────────┘                └───
pid  ────────────┘                └───
st   ──────────────────────────────────────
1214            by rw [← zero_add (degree X), degree_mul_eq' this];
id                      └──────┘  └────┘    └────────────┘ └──┘
src  ─────────┘  └────┘└──────┘ └────┘└─┘└────────────┘    └─
typ  ─────────┘  └────┘└──────┘ └────┘└─┘└────────────┘└──┘└─
doc  ─────────┘  └────┘         └────┘└─┘                  └─
txt  ─────────┘  └────┘                └─┘                  └─
par  ─────────┘  └────┘                └─┘                  └─
pid  ─────────┘  └─────┘                └─┘                  └──
st   ───────────┘└────────────────────────┘└───────────────────┘└─
1215              exact add_le_add'
id                     └─────────┘
src  ─────────────────┘└─────────┘
typ  ─────────────────┘└─────────┘
doc  ─────────────────┘           
txt  ─────────────────┘           
par  ─────────────────┘           
pid  ─────────────────┘           
st   ──────────────────────────────
1216                (by rw [zero_le_degree_iff, ne.def, div_X_eq_zero_iff];
id                         └────────────────┘  └────┘  └───────────────┘
src  ─────────────┘   └──┘└────────────────┘└┘└────┘└┘└───────────────┘└─
typ  ─────────────┘   └──┘└────────────────┘└┘└────┘└┘└───────────────┘└─
doc  ─────────────┘   └──┘                  └┘      └┘                 └─
txt  ─────────────┘   └──┘                  └┘      └┘                 └─
par  ─────────────┘   └──┘                  └┘      └┘                 └─
pid  ─────────────┘   └───┘                  └┘      └┘                 └──
st   ────────────────┘└─────────────────────┘└──────┘└─────────────────┘└─
1217                  exact λ h0, h (h0.symm ▸ degree_C_le))
id                                   └───┘  └─────────┘
src  ─────────────────────┘ └───┘    └───┘└─────────┘└──
typ  ─────────────────────┘ └───┘   └───┘└─────────┘└──
doc  ─────────────────────┘ └───┘                     └──
txt  ─────────────────────┘ └───┘                     └──
par  ─────────────────────┘ └───┘                     └──
pid  ─────────────────────┘ └───┘                     └──
st   ────────────────────────────────────────────────────┘└─
1218                (le_refl _),
id                  └─────┘
src  ─────────────┘ └─────┘└────
typ  ─────────────┘ └─────┘└────
doc  ─────────────┘        └────
txt  ─────────────┘        └────
par  ─────────────┘        └────
pid  ─────────────┘        └────
st   ────────────────────────┘└─
1219      by rw [add_comm, degree_add_eq_of_degree_lt this];
id              └──────┘  └────────────────────────┘ └──┘
src  ───┘  └──┘└──────┘└┘└────────────────────────┘    └─
typ  ───┘  └──┘└──────┘└┘└────────────────────────┘└──┘└─
doc  ───┘  └──┘        └┘                              └─
txt  ───┘  └──┘        └┘                              └─
par  ───┘  └──┘        └┘                              └─
pid  ───┘  └───┘        └┘                              └──
st   ─────┘└───────────┘└───────────────────────────────┘└─
1220        exact degree_lt_degree_mul_X hXp0
id               └────────────────────┘ └──┘
src  ───────────┘└────────────────────┘    
typ  ───────────┘└────────────────────┘└──┘
doc  ───────────┘                          
txt  ───────────┘                          
par  ───────────┘                          
pid  ───────────┘                          
st   ───────────────────────────────────────┘
1221  ... = p.degree : by rw div_X_mul_X_add
id         └──────┘         └─────────────┘
src  ───┘ └──────┘└─┘  └─┘└─────────────┘
typ  ───┘ └──────┘└─┘  └─┘└─────────────┘
doc  ───┘ └──────┘└─┘  └─┘               
txt  ───┘         └─┘  └─┘               
par  ───┘         └─┘  └─┘               
pid  ───┘         └─┘  └──┘               
st   └─────────────────┘└───────────────────
1222  
src  
typ  
doc  
txt  
par  
pid  
st   
1223  @[elab_as_eliminator] noncomputable def rec_on_horner
doc    └────────────────┘
1224    {M : polynomial α → Sort*} : Π (p : polynomial α),
id          └────────┘                   └────────┘ 
src         └────────┘                     └────────┘
typ         └────────┘                   └────────┘ 
doc         └────────┘                     └────────┘
1225    M 0 →
id     
typ    
1226    (Π p a, coeff p 0 = 0 → a ≠ 0 → M p → M (p + C a)) →
id           └───┘                        
src            └───┘                             
typ          └───┘                        
doc            └───┘                                
1227    (Π p, p ≠ 0 → M p → M (p * X)) →
id                        
src                             
typ                       
doc                               
1228    M p
id      
typ     
1229  | p := λ M0 MC MX,
id           └┘ └┘ └┘
typ          └┘ └┘ └┘
1230  if hp : p = 0 then eq.rec_on hp.symm M0
id   └┘                └───────┘ └┘└───┘ └┘
src  └┘                └───────┘   └───┘
typ  └┘                └───────┘ └┘└───┘ └┘
1231  else
1232  have wf : degree (div_X p) < degree p,
id   └──┘      └────┘  └───┘     └────┘
src            └────┘  └───┘     └────┘
typ  └──┘      └────┘  └───┘     └────┘
doc            └────┘  └───┘      └────┘
1233    from degree_div_X_lt hp,
id          └─────────────┘ └┘
src         └─────────────┘
typ         └─────────────┘ └┘
1234  by rw [← div_X_mul_X_add p] at *;
id            └─────────────┘ 
src     └────┘└─────────────┘ └────┘
typ     └────┘└─────────────┘└────┘
doc     └────┘                └────┘
txt     └────┘                └────┘
par     └────┘                └────┘
pid       └──┘                └───┘
st     └──────────────────────┘└──────
1235    exact
src    └─────
typ    └─────
doc    └─────
txt    └─────
par    └─────
pid         
st   ────────
1236    if hcp0 : coeff p 0 = 0
id     └┘        └───┘     
src  ─┘└┘└──────┘└───┘ └─┘└──
typ  ─┘└┘└──────┘└───┘ └─┘└──
doc  ─┘  └──────┘└───┘ └─┘ └──
txt  ─┘  └──────┘      └─┘ └──
par  ─┘  └──────┘      └─┘ └──
pid  ─┘  └──────┘      └─┘ └──
st   ──────────────────────────
1237    then by rw [hcp0, C_0, add_zero];
id                 └──┘  └─┘  └──────┘
src  ──────┘  └──┘    └┘└─┘└┘└──────┘└─
typ  ──────┘  └──┘└──┘└┘└─┘└┘└──────┘└─
doc  ──────┘  └──┘    └┘   └┘        └─
txt  ──────┘  └──┘    └┘   └┘        └─
par  ──────┘  └──┘    └┘   └┘        └─
pid  ──────┘  └───┘    └┘   └┘        └──
st   ────────┘└───────┘└───┘└────────┘└─
1238      exact MX _ (λ h : div_X p = 0, by simpa [h, hcp0] using hp)
id                         └───┘                   └──┘        └┘
src  ─────────┘  └─┘  └───┘└───┘  └──┘  └─────┘ └┘    └──────┘  └─
typ  ─────────┘  └─┘  └───┘└───┘ └──┘  └─────┘└┘└──┘└──────┘└┘└─
doc  ─────────┘  └─┘  └───┘└───┘  └──┘  └─────┘ └┘    └──────┘  └─
txt  ─────────┘  └─┘  └───┘       └──┘  └─────┘ └┘    └──────┘  └─
par  ─────────┘  └─┘  └───┘       └──┘  └─────┘ └┘    └──────┘  └─
pid  ─────────┘  └─┘  └───┘       └──┘  └──────┘ └┘    └──────┘  └─
st   ────────────────────────────────────┘└───────────────────────┘└─
1239        (rec_on_horner _ M0 MC MX)
id          └───────────┘   └┘ └┘ └┘
src  ─────┘              └─┘      └─
typ  ─────┘ └───────────┘└─┘└┘└┘└┘└─
doc  ─────┘              └─┘      └─
txt  ─────┘              └─┘      └─
par  ─────┘              └─┘      └─
pid  ─────┘              └─┘      └─
st   ─────────────────────────────────
1240    else MC _ _ (coeff_mul_X_zero _) hcp0 (if hpX0 : div_X p = 0
id          └┘      └──────────────┘                            
src  ──────┘  └───┘ └──────────────┘└──┘       └──────┘       └──
typ  ──────┘└┘└───┘ └──────────────┘└──┘       └──────┘      └──
doc  ──────┘  └───┘                 └──┘       └──────┘       └──
txt  ──────┘  └───┘                 └──┘       └──────┘       └──
par  ──────┘  └───┘                 └──┘       └──────┘       └──
pid  ──────┘  └───┘                 └──┘       └──────┘       └──
st   ─┘└────────────────────────────────────────────────────────────
1241      then show M (div_X p * X), by rw [hpX0, zero_mul]; exact M0
id                                      └──┘  └──────┘         └┘
src  ────────┘            └────┘└──┘    └┘└──────┘└──────┘  
typ  ────────┘           └────┘└──┘└──┘└┘└──────┘└──────┘└┘
doc  ────────┘             └────┘└──┘    └┘        └──────┘  
txt  ────────┘              └────┘└──┘    └┘        └──────┘  
par  ────────┘              └────┘└──┘    └┘        └──────┘  
pid  ────────┘              └────────┘    └┘        └───────┘  
st   ────────────────────────────────┘└───────┘└────────┘└──────────
1242      else MX (div_X p) hpX0 (rec_on_horner _ M0 MC MX))
id            └┘        
src  ────────┘         └┘                  └─┘      └─┘
typ  ────────┘└┘      └┘                  └─┘      └─┘
doc  ────────┘         └┘                  └─┘      └─┘
txt  ────────┘         └┘                  └─┘      └─┘
par  ────────┘         └┘                  └─┘      └─┘
pid  ────────┘         └┘                  └─┘      └┘
st   ───┘└─────────────────────────────────────────────────┘
1243  using_well_founded {dec_tac := tactic.assumption}
id                                  └───────────────┘
src                                 └───────────────┘
typ                                 └───────────────┘
1244  
1245  @[elab_as_eliminator] lemma degree_pos_induction_on
doc    └────────────────┘
1246    {P : polynomial α → Prop} (p : polynomial α) (h0 : 0 < degree p)
id          └────────┘               └────────┘            └────┘ 
src         └────────┘                └────────┘             └────┘
typ         └────────┘               └────────┘            └────┘ 
doc         └────────┘                └────────┘              └────┘
1247    (hC : ∀ {a}, a ≠ 0 → P (C a * X))
id                            
src                               
typ                           
doc                                 
1248    (hX : ∀ {p}, 0 < degree p → P p → P (p * X))
id                    └────┘            
src                    └────┘                 
typ                   └────┘            
doc                     └────┘                  
1249    (hadd : ∀ {p} {a}, 0 < degree p → P p → P (p + C a)) : P p :=
id                         └────┘                   
src                          └────┘                 
typ                        └────┘                   
doc                           └────┘                  
1250  rec_on_horner p
id   └───────────┘ 
src  └───────────┘
typ  └───────────┘ 
1251    (λ h, by rw degree_zero at h; exact absurd h dec_trivial)
id                └─────────┘             └────┘  └─────────┘
src             └─┘└─────────┘└───┘  └────┘└────┘ └─────────┘
typ            └─┘└─────────┘└───┘  └────┘└────┘└─────────┘
doc             └─┘           └───┘  └────┘       └─────────┘
txt             └─┘           └───┘  └────┘       
par             └─┘           └───┘  └────┘       
pid                          └───┘              
st             └──────────────────────────────────────────────┘
1252    (λ p a _ _ ih h0,
id            └┘ └┘
typ           └┘ └┘
1253      have 0 < degree p,
id               └────┘ 
src              └────┘
typ              └────┘ 
doc               └────┘
1254        from lt_of_not_ge (λ h, (not_lt_of_ge degree_C_le) $
id              └──────────┘       └──────────┘ └─────────┘
src             └──────────┘        └──────────┘ └─────────┘
typ             └──────────┘       └──────────┘ └─────────┘
1255          by rwa [eq_C_of_degree_le_zero h, ← C_add] at h0),
id                   └────────────────────┘     └───┘
src             └───┘└────────────────────┘ └──┘└───┘└─────┘
typ             └───┘└────────────────────┘└──┘└───┘└─────┘
doc             └───┘                       └──┘     └─────┘
txt             └───┘                       └──┘     └─────┘
par             └───┘                       └──┘     └─────┘
pid                └┘                       └──┘     └────┘
st             └────────────────────────────┘└───────┘└────┘
1256      hadd this (ih this))
id       └──┘ └──┘  └┘ └──┘
typ      └──┘ └──┘  └┘ └──┘
1257    (λ p _ ih h0',
id          └┘ └─┘
typ         └┘ └─┘
1258      if h0 : 0 < degree p
id       └┘         └────┘ 
src      └┘         └────┘
typ      └┘         └────┘ 
doc                  └────┘
1259      then hX h0 (ih h0)
id            └┘ └┘  └┘ └┘
typ           └┘ └┘  └┘ └┘
1260      else by rw [eq_C_of_degree_le_zero (le_of_not_gt h0)] at *;
id                   └────────────────────┘  └──────────┘ └┘
src              └──┘└────────────────────┘ └──────────┘  └─────┘
typ              └──┘└────────────────────┘ └──────────┘└┘└─────┘
doc              └──┘                                     └─────┘
txt              └──┘                                     └─────┘
par              └──┘                                     └─────┘
pid                └┘                                     └┘└───┘
st              └───────────────────────────────────────────┘└──────
1261        exact hC (λ h : coeff p 0 = 0,
id               └┘        └───┘    
src        └────┘    └───┘└───┘ └─┘└───
typ        └────┘└┘  └───┘└───┘└─┘└───
doc        └────┘    └───┘└───┘ └─┘ └───
txt        └────┘    └───┘      └─┘ └───
par        └────┘    └───┘      └─┘ └───
pid                 └───┘      └─┘ └───
st   ─────────────────────────────────────
1262          by simpa [h, not_lt.2 (@lattice.bot_le (  ℕ) _ _)] using h0'))
id                       └────┘     └────────────┘                   └─┘
src  ───────┘  └─────┘ └┘└────┘└─┘  └────────────┘ └┘ └────────────┘   
typ  ───────┘  └─────┘└┘└────┘└─┘  └────────────┘ └┘ └────────────┘└─┘
doc  ───────┘  └─────┘ └┘      └─┘                 └┘ └────────────┘   
txt  ───────┘  └─────┘ └┘      └─┘                 └┘ └────────────┘   
par  ───────┘  └─────┘ └┘      └─┘                 └┘ └────────────┘   
pid  ───────┘  └──────┘ └┘      └─┘                 └┘ └────────────┘   
st   ─────────┘└────────────────────────────────────────────────────────┘
1263    h0
id     └┘
typ    └┘
1264  
1265  end comm_semiring
1266  
1267  section comm_ring
1268  variables [comm_ring α] {p q : polynomial α}
id              └───────┘           └────────┘
src             └───────┘           └────────┘
typ             └───────┘           └────────┘
doc                                 └────────┘
1269  instance : comm_ring (polynomial α) := finsupp.comm_ring
id              └───────┘  └────────┘      └───────────────┘
src             └───────┘  └────────┘       └───────────────┘
typ             └───────┘  └────────┘      └───────────────┘
doc                        └────────┘
1270  instance : has_scalar α (polynomial α) := finsupp.has_scalar
id              └────────┘   └────────┘      └────────────────┘
src             └────────┘    └────────┘       └────────────────┘
typ             └────────┘   └────────┘      └────────────────┘
doc             └────────┘    └────────┘
1271  -- TODO if this becomes a semimodule then the below lemma could be proved for semimodules
1272  instance : module α (polynomial α) := finsupp.module ℕ α
id              └────┘   └────────┘      └────────────┘  
src             └────┘    └────────┘       └────────────┘ 
typ             └────┘   └────────┘      └────────────┘  
doc             └────┘    └────────┘
1273  
1274  -- TODO -- this is OK for semimodules
1275  @[simp] lemma coeff_smul (p : polynomial α) (r : α) (n : ℕ) :
id                                 └────────┘               
src                                └────────┘                 
typ                                └────────┘               
doc    └──┘                        └────────┘
1276  coeff (r • p) n = r * coeff p n := finsupp.smul_apply
id   └───┘          └───┘      └────────────────┘
src  └───┘              └───┘        └────────────────┘
typ  └───┘          └───┘      └────────────────┘
doc  └───┘                 └───┘
1277  
1278  -- TODO -- this is OK for semimodules
1279  lemma C_mul' (a : α) (f : polynomial α) : C a * f = a • f :=
id                            └────────┘            
src                            └────────┘               
typ                           └────────┘            
doc                            └────────┘      
1280  ext $ λ n, coeff_C_mul f
id   └─┘       └─────────┘ 
src  └─┘        └─────────┘
typ  └─┘       └─────────┘ 
1281  
1282  variable (α)
1283  def lcoeff (n : ℕ) : polynomial α →ₗ α :=
id                       └────────┘  └┘ 
src                      └────────┘   └┘
typ                      └────────┘  └┘ 
doc                       └────────┘
1284  { to_fun := λ f, coeff f n,
id                   └───┘  
src                   └───┘
typ                  └───┘  
doc                   └───┘
1285    add := λ f g, coeff_add f g n,
id                 └───────┘   
src                  └───────┘
typ                └───────┘   
1286    smul := λ r p, coeff_smul p r n }
id                  └────────┘   
src                   └────────┘
typ                 └────────┘   
1287  variable {α}
1288  
1289  @[simp] lemma lcoeff_apply (n : ℕ) (f : polynomial α) : lcoeff α n f = coeff f n := rfl
id                                          └────────┘     └────┘     └───┘      └─┘
src                                         └────────┘      └────┘        └───┘        └─┘
typ                                         └────────┘     └────┘     └───┘      └─┘
doc    └──┘                                  └────────┘                     └───┘
1290  
1291  instance C.is_ring_hom : is_ring_hom (@C α _) := by apply is_ring_hom.of_semiring
id                            └─────────┘                    └─────────────────────┘
src                           └─────────┘               └────┘└─────────────────────┘
typ                           └─────────┘              └────┘└─────────────────────┘
doc                           └─────────┘               └────┘└─────────────────────┘
txt                                                      └────┘                       
par                                                      └────┘                       
pid                                                                                  
st                                                      └──────────────────────────────
1292  
src  
typ  
doc  
txt  
par  
pid  
st   
1293  lemma int_cast_eq_C (n : ℤ) : (n : polynomial α) = C n :=
id                                    └────────┘     
src                                    └────────┘     
typ                                   └────────┘     
doc                                     └────────┘      
1294  congr_fun (int.eq_cast' _).symm n
id   └───────┘  └──────────┘   └──┘  
src  └───────┘  └──────────┘   └──┘
typ  └───────┘  └──────────┘   └──┘  
1295  
1296  @[simp] lemma C_neg : C (-a) = -C a := is_ring_hom.map_neg C
id                                   └─────────────────┘ 
src                                    └─────────────────┘ 
typ                                  └─────────────────┘ 
doc    └──┘                               └─────────────────┘ 
1297  
1298  @[simp] lemma C_sub : C (a - b) = C a - C b := is_ring_hom.map_sub C
id                                        └─────────────────┘ 
src                                           └─────────────────┘ 
typ                                       └─────────────────┘ 
doc    └──┘                                      └─────────────────┘ 
1299  
1300  instance eval₂.is_ring_hom {β} [comm_ring β]
id                                   └───────┘ 
src                                  └───────┘
typ                                  └───────┘ 
1301    (f : α → β) [is_ring_hom f] {x : β} : is_ring_hom (eval₂ f x) :=
id                └─────────┘            └─────────┘  └───┘  
src                 └─────────┘              └─────────┘  └───┘
typ               └─────────┘            └─────────┘  └───┘  
doc                 └─────────┘              └─────────┘  └───┘
1302  by apply is_ring_hom.of_semiring
id            └─────────────────────┘
src     └────┘└─────────────────────┘
typ     └────┘└─────────────────────┘
doc     └────┘└─────────────────────┘
txt     └────┘                       
par     └────┘                       
pid                                 
st     └──────────────────────────────
1303  
src  
typ  
doc  
txt  
par  
pid  
st   
1304  instance eval.is_ring_hom {x : α} : is_ring_hom (eval x) := eval₂.is_ring_hom _
id                                      └─────────┘  └──┘      └───────────────┘
src                                      └─────────┘  └──┘       └───────────────┘
typ                                     └─────────┘  └──┘      └───────────────┘
doc                                      └─────────┘  └──┘
1305  
1306  instance map.is_ring_hom {β} [comm_ring β]
id                                 └───────┘ 
src                                └───────┘
typ                                └───────┘ 
1307    (f : α → β) [is_ring_hom f] : is_ring_hom (map f) :=
id                └─────────┘     └─────────┘  └─┘ 
src                 └─────────┘      └─────────┘  └─┘
typ               └─────────┘     └─────────┘  └─┘ 
doc                 └─────────┘      └─────────┘  └─┘
1308  eval₂.is_ring_hom (C ∘ f)
id   └───────────────┘    
src  └───────────────┘   
typ  └───────────────┘    
doc                     
1309  
1310  @[simp] lemma map_sub {β} [comm_ring β]
id                              └───────┘ 
src                             └───────┘
typ                             └───────┘ 
doc    └──┘
1311    (f : α → β) [is_ring_hom f] : (p - q).map f = p.map f - q.map f := is_ring_hom.map_sub _
id                └─────────┘         └─┘    └──┘   └──┘     └─────────────────┘
src                 └─────────┘            └─┘      └──┘     └──┘      └─────────────────┘
typ               └─────────┘         └─┘    └──┘   └──┘     └─────────────────┘
doc                 └─────────┘             └─┘       └──┘      └──┘      └─────────────────┘
1312  
1313  @[simp] lemma map_neg {β} [comm_ring β]
id                              └───────┘ 
src                             └───────┘
typ                             └───────┘ 
doc    └──┘
1314    (f : α → β) [is_ring_hom f] : (-p).map f = -(p.map f) := is_ring_hom.map_neg _
id                └─────────┘       └─┘     └──┘      └─────────────────┘
src                 └─────────┘         └─┘       └──┘       └─────────────────┘
typ               └─────────┘       └─┘     └──┘      └─────────────────┘
doc                 └─────────┘          └─┘         └──┘       └─────────────────┘
1315  
1316  @[simp] lemma degree_neg (p : polynomial α) : degree (-p) = degree p :=
id                                 └────────┘     └────┘     └────┘ 
src                                └────────┘      └────┘      └────┘
typ                                └────────┘     └────┘     └────┘ 
doc    └──┘                        └────────┘      └────┘        └────┘
1317  by unfold degree; rw support_neg
id                        └─────────┘
src     └───────────┘  └─┘└─────────┘
typ     └───────────┘  └─┘└─────────┘
doc     └───────────┘  └─┘           
txt     └───────────┘  └─┘           
par     └───────────┘  └─┘           
pid           └─────┘               
st     └─────────────────┘└─────────┘
1318  
src  
typ  
doc  
txt  
par  
pid  
st   
1319  @[simp] lemma nat_degree_neg (p : polynomial α) : nat_degree (-p) = nat_degree p :=
id                                     └────────┘     └────────┘     └────────┘ 
src                                    └────────┘      └────────┘      └────────┘
typ                                    └────────┘     └────────┘     └────────┘ 
doc    └──┘                            └────────┘      └────────┘        └────────┘
1320  by simp [nat_degree]
id            └────────┘
src     └────┘└────────┘└─
typ     └────┘└────────┘└─
doc     └────┘└────────┘└─
txt     └────┘          └─
par     └────┘          └─
pid                   
st     └──────────────────
1321  
src  
typ  
doc  
txt  
par  
pid  
st   
1322  @[simp] lemma nat_degree_int_cast (n : ℤ) : nat_degree (n : polynomial α) = 0 :=
id                                              └────────┘     └────────┘   
src                                             └────────┘      └────────┘    
typ                                             └────────┘     └────────┘   
doc    └──┘                                      └────────┘      └────────┘
1323  by simp [int_cast_eq_C]
id            └───────────┘
src     └────┘└───────────┘└─
typ     └────┘└───────────┘└─
doc     └────┘             └─
txt     └────┘             └─
par     └────┘             └─
pid                      
st     └─────────────────────
1324  
src  
typ  
doc  
txt  
par  
pid  
st   
1325  @[simp] lemma coeff_neg (p : polynomial α) (n : ℕ) : coeff (-p) n = -coeff p n := rfl
id                                └────────┘            └───┘      └───┘      └─┘
src                               └────────┘             └───┘        └───┘        └─┘
typ                               └────────┘            └───┘      └───┘      └─┘
doc    └──┘                       └────────┘              └───┘           └───┘
1326  
1327  @[simp] lemma coeff_sub (p q : polynomial α) (n : ℕ) : coeff (p - q) n = coeff p n - coeff q n := rfl
id                                  └────────┘            └───┘        └───┘    └───┘      └─┘
src                                 └────────┘             └───┘           └───┘      └───┘        └─┘
typ                                 └────────┘            └───┘        └───┘    └───┘      └─┘
doc    └──┘                         └────────┘              └───┘             └───┘       └───┘
1328  
1329  @[simp] lemma eval₂_neg {β} [comm_ring β] (f : α → β) [is_ring_hom f] {x : β} :
id                                └───────┘              └─────────┘        
src                               └───────┘                 └─────────┘
typ                               └───────┘              └─────────┘        
doc    └──┘                                                 └─────────┘
1330    (-p).eval₂ f x = -p.eval₂ f x :=
id       └───┘     └────┘  
src       └───┘        └────┘
typ      └───┘     └────┘  
doc        └───┘          └────┘
1331  is_ring_hom.map_neg _
id   └─────────────────┘
src  └─────────────────┘
typ  └─────────────────┘
doc  └─────────────────┘
1332  
1333  @[simp] lemma eval₂_sub {β} [comm_ring β] (f : α → β) [is_ring_hom f] {x : β} :
id                                └───────┘              └─────────┘        
src                               └───────┘                 └─────────┘
typ                               └───────┘              └─────────┘        
doc    └──┘                                                 └─────────┘
1334    (p - q).eval₂ f x = p.eval₂ f x - q.eval₂ f x :=
id         └───┘     └────┘    └────┘  
src          └───┘        └────┘       └────┘
typ        └───┘     └────┘    └────┘  
doc           └───┘         └────┘        └────┘
1335  is_ring_hom.map_sub _
id   └─────────────────┘
src  └─────────────────┘
typ  └─────────────────┘
doc  └─────────────────┘
1336  
1337  @[simp] lemma eval_neg (p : polynomial α) (x : α) : (-p).eval x = -p.eval x :=
id                               └────────┘              └──┘    └───┘ 
src                              └────────┘                 └──┘      └───┘
typ                              └────────┘              └──┘    └───┘ 
doc    └──┘                      └────────┘                  └──┘        └───┘
1338  is_ring_hom.map_neg _
id   └─────────────────┘
src  └─────────────────┘
typ  └─────────────────┘
doc  └─────────────────┘
1339  
1340  @[simp] lemma eval_sub (p q : polynomial α) (x : α) : (p - q).eval x = p.eval x - q.eval x :=
id                                 └────────┘                └──┘    └───┘   └───┘ 
src                                └────────┘                    └──┘      └───┘     └───┘
typ                                └────────┘                └──┘    └───┘   └───┘ 
doc    └──┘                        └────────┘                     └──┘       └───┘      └───┘
1341  is_ring_hom.map_sub _
id   └─────────────────┘
src  └─────────────────┘
typ  └─────────────────┘
doc  └─────────────────┘
1342  
1343  lemma degree_sub_lt (hd : degree p = degree q)
id                             └────┘   └────┘ 
src                            └────┘    └────┘
typ                            └────┘   └────┘ 
doc                            └────┘     └────┘
1344    (hp0 : p ≠ 0) (hlc : leading_coeff p = leading_coeff q) :
id                        └───────────┘   └───────────┘ 
src                        └───────────┘    └───────────┘
typ                       └───────────┘   └───────────┘ 
doc                         └───────────┘     └───────────┘
1345    degree (p - q) < degree p :=
id     └────┘       └────┘ 
src    └────┘         └────┘
typ    └────┘       └────┘ 
doc    └────┘           └────┘
1346  have hp : single (nat_degree p) (leading_coeff p) + p.erase (nat_degree p) = p :=
id             └────┘  └────────┘    └───────────┘    └────┘  └────────┘    
src            └────┘  └────────┘     └───────────┘      └────┘  └────────┘    
typ            └────┘  └────────┘    └───────────┘    └────┘  └────────┘    
doc            └────┘  └────────┘     └───────────┘               └────────┘
1347    finsupp.single_add_erase,
id     └──────────────────────┘
src    └──────────────────────┘
typ    └──────────────────────┘
1348  have hq : single (nat_degree q) (leading_coeff q) + q.erase (nat_degree q) = q :=
id             └────┘  └────────┘    └───────────┘    └────┘  └────────┘    
src            └────┘  └────────┘     └───────────┘      └────┘  └────────┘    
typ            └────┘  └────────┘    └───────────┘    └────┘  └────────┘    
doc            └────┘  └────────┘     └───────────┘               └────────┘
1349    finsupp.single_add_erase,
id     └──────────────────────┘
src    └──────────────────────┘
typ    └──────────────────────┘
1350  have hd' : nat_degree p = nat_degree q := by unfold nat_degree; rw hd,
id              └────────┘   └────────┘                              └┘
src             └────────┘    └────────┘         └───────────────┘  └─┘
typ             └────────┘   └────────┘        └───────────────┘  └─┘└┘
doc             └────────┘     └────────┘         └───────────────┘  └─┘
txt                                               └───────────────┘  └─┘
par                                               └───────────────┘  └─┘
pid                                                     └─────────┘    
st                                               └─────────────────────┘└┘
1351  have hq0 : q ≠ 0 := mt degree_eq_bot.2 (hd ▸ mt degree_eq_bot.1 hp0),
id                     └┘ └───────────┘   └┘  └┘ └───────────┘  └─┘
src                     └┘ └───────────┘       └┘ └───────────┘
typ                    └┘ └───────────┘   └┘  └┘ └───────────┘  └─┘
1352  calc degree (p - q) = degree (erase (nat_degree q) p + -erase (nat_degree q) q) :
id        └────┘        └────┘  └───┘  └────────┘     └───┘  └────────┘   
src       └────┘          └────┘  └───┘  └────────┘       └───┘  └────────┘
typ       └────┘        └────┘  └───┘  └────────┘     └───┘  └────────┘   
doc       └────┘           └────┘         └────────┘                └────────┘
1353    by conv {to_lhs, rw [← hp, ← hq, hlc, hd', add_sub_add_left_eq_sub, sub_eq_add_neg]}
id                            └┘    └┘  └─┘  └─┘  └─────────────────────┘  └────────────┘
src       └────┘└────┘└┘└────┘  └──┘  └┘   └┘   └┘└─────────────────────┘└┘└────────────┘└┘
typ       └────┘└────┘└┘└────┘└┘└──┘└┘└┘└─┘└┘└─┘└┘└─────────────────────┘└┘└────────────┘└┘
txt       └────┘└────┘└┘└────┘  └──┘  └┘   └┘   └┘                       └┘              └┘
par       └────┘└────┘└┘└────┘  └──┘  └┘   └┘   └┘                       └┘              └┘
pid           └─────────────┘  └──┘  └┘   └┘   └┘                       └┘              └┘
st       └─────┘└────┘└────────┘└────┘└───┘└───┘└───────────────────────┘└──────────────┘ 
1354  ... ≤ max (degree (erase (nat_degree q) p)) (degree (erase (nat_degree q) q))
id         └─┘  └────┘  └───┘  └────────┘       └────┘  └───┘  └────────┘   
src        └─┘  └────┘  └───┘  └────────┘         └────┘  └───┘  └────────┘
typ        └─┘  └────┘  └───┘  └────────┘       └────┘  └───┘  └────────┘   
doc             └────┘         └────────┘         └────┘         └────────┘
1355    : degree_neg (erase (nat_degree q) q) ▸ degree_add_le _ _
id       └────────┘  └───┘  └────────┘      └───────────┘
src      └────────┘  └───┘  └────────┘        └───────────┘
typ      └────────┘  └───┘  └────────┘      └───────────┘
doc                         └────────┘
1356  ... < degree p : max_lt_iff.2 ⟨hd' ▸ degree_erase_lt hp0, hd.symm ▸ degree_erase_lt hq0⟩
id         └────┘    └────────┘   └─┘  └─────────────┘ └─┘  └┘└───┘  └─────────────┘ └─┘
src        └────┘     └────────┘        └─────────────┘        └───┘  └─────────────┘
typ        └────┘    └────────┘   └─┘  └─────────────┘ └─┘  └┘└───┘  └─────────────┘ └─┘
doc        └────┘
1357  
1358  lemma ne_zero_of_ne_zero_of_monic (hp : p ≠ 0) (hq : monic q) : q ≠ 0
id                                                      └───┘      
src                                                      └───┘        
typ                                                     └───┘      
doc                                                       └───┘
1359  | h := begin
st          └─────
1360    rw [h, monic.def, leading_coeff_zero] at hq,
id           └───────┘  └────────────────┘
src    └──┘ └┘└───────┘└┘└────────────────┘└─────┘
typ    └──┘└┘└───────┘└┘└────────────────┘└─────┘
doc    └──┘ └┘         └┘                  └─────┘
txt    └──┘ └┘         └┘                  └─────┘
par    └──┘ └┘         └┘                  └─────┘
pid      └┘ └┘         └┘                  └────┘
st   ──────┘└─────────┘└──────────────────┘└────┘└─
1361    rw [← mul_one p, ← C_1, ← hq, C_0, mul_zero] at hp,
id           └─────┘     └─┘    └┘  └─┘  └──────┘
src    └────┘└─────┘ └──┘└─┘└──┘  └┘└─┘└┘└──────┘└─────┘
typ    └────┘└─────┘└──┘└─┘└──┘└┘└┘└─┘└┘└──────┘└─────┘
doc    └────┘        └──┘   └──┘  └┘   └┘        └─────┘
txt    └────┘        └──┘   └──┘  └┘   └┘        └─────┘
par    └────┘        └──┘   └──┘  └┘   └┘        └─────┘
pid      └──┘        └──┘   └──┘  └┘   └┘        └────┘
st   ────────────────┘└─────┘└────┘└───┘└────────┘└────┘└─
1362    exact hp rfl
id           └┘ └─┘
src    └────┘  └─┘
typ    └────┘└┘└─┘
doc    └────┘     
txt    └────┘     
par    └────┘     
pid              
st   ──────────────┘
1363  end
st   └─┘
1364  
1365  lemma div_wf_lemma (h : degree q ≤ degree p ∧ p ≠ 0) (hq : monic q) :
id                           └────┘   └────┘              └───┘ 
src                          └────┘    └────┘                └───┘
typ                          └────┘   └────┘              └───┘ 
doc                          └────┘     └────┘                  └───┘
1366    degree (p - C (leading_coeff p) * X ^ (nat_degree p - nat_degree q) * q) < degree p :=
id     └────┘      └───────────┘       └────────┘   └────────┘       └────┘ 
src    └────┘       └───────────┘        └────────┘    └────────┘         └────┘
typ    └────┘      └───────────┘       └────────┘   └────────┘       └────┘ 
doc    └────┘        └───────────┘          └────────┘     └────────┘           └────┘
1367  have hp : leading_coeff p ≠ 0 := mt leading_coeff_eq_zero.1 h.2,
id             └───────────┘        └┘ └───────────────────┘  
src            └───────────┘         └┘ └───────────────────┘   
typ            └───────────┘        └┘ └───────────────────┘  
doc            └───────────┘
1368  have hpq : leading_coeff (C (leading_coeff p) * X ^ (nat_degree p - nat_degree q)) *
id              └───────────┘    └───────────┘       └────────┘   └────────┘    
src             └───────────┘    └───────────┘        └────────┘    └────────┘     
typ             └───────────┘    └───────────┘       └────────┘   └────────┘    
doc             └───────────┘    └───────────┘          └────────┘     └────────┘
1369      leading_coeff q ≠ 0,
id       └───────────┘  
src      └───────────┘   
typ      └───────────┘  
doc      └───────────┘
1370    by rwa [leading_coeff_monomial, monic.def.1 hq, mul_one],
id             └────────────────────┘  └───────┘   └┘  └─────┘
src       └───┘└────────────────────┘└┘└───────┘└─┘  └┘└─────┘
typ       └───┘└────────────────────┘└┘└───────┘└─┘└┘└┘└─────┘
doc       └───┘                      └┘         └─┘  └┘       
txt       └───┘                      └┘         └─┘  └┘       
par       └───┘                      └┘         └─┘  └┘       
pid          └┘                      └┘         └─┘  └┘       
st       └──────────────────────────┘└──────────────┘└───────┘
1371  if h0 : p - C (leading_coeff p) * X ^ (nat_degree p - nat_degree q) * q = 0
id   └┘          └───────────┘       └────────┘   └────────┘     
src  └┘           └───────────┘        └────────┘    └────────┘       
typ  └┘          └───────────┘       └────────┘   └────────┘     
doc                └───────────┘          └────────┘     └────────┘
1372  then h0.symm ▸ (lt_of_not_ge $ mt le_bot_iff.1 (mt degree_eq_bot.1 h.2))
id        └┘└───┘   └──────────┘   └┘ └────────┘   └┘ └───────────┘  
src         └───┘   └──────────┘   └┘ └────────┘   └┘ └───────────┘   
typ       └┘└───┘   └──────────┘   └┘ └────────┘   └┘ └───────────┘  
1373  else
1374    have hq0 : q ≠ 0 := ne_zero_of_ne_zero_of_monic h.2 hq,
id     └──┘              └─────────────────────────┘   └┘
src                       └─────────────────────────┘  
typ    └──┘              └─────────────────────────┘   └┘
1375    have hlt : nat_degree q ≤ nat_degree p := with_bot.coe_le_coe.1
id                └────────┘   └────────┘     └─────────────────┘
src               └────────┘    └────────┘      └─────────────────┘
typ               └────────┘   └────────┘     └─────────────────┘
doc               └────────┘     └────────┘
1376      (by rw [← degree_eq_nat_degree h.2, ← degree_eq_nat_degree hq0];
id                 └──────────────────┘       └──────────────────┘ └─┘
src          └────┘└──────────────────┘ └────┘└──────────────────┘   
typ          └────┘└──────────────────┘└────┘└──────────────────┘└─┘
doc          └────┘                     └────┘                       
txt          └────┘                     └────┘                       
par          └────┘                     └────┘                       
pid            └──┘                     └────┘                       
st          └───────────────────────────┘└────────────────────────────┘└─
1377      exact h.1),
id             
src      └────┘ └┘
typ      └────┘└┘
doc      └────┘ └┘
txt      └────┘ └┘
par      └────┘ └┘
pid            └┘
st   ────────────┘
1378    degree_sub_lt
id     └───────────┘
src    └───────────┘
typ    └───────────┘
1379    (by rw [degree_mul_eq' hpq, degree_monomial _ hp, degree_eq_nat_degree h.2,
id             └────────────┘ └─┘  └─────────────┘   └┘  └──────────────────┘ 
src        └──┘└────────────┘   └┘└─────────────┘└─┘  └┘└──────────────────┘ └───
typ        └──┘└────────────┘└─┘└┘└─────────────┘└─┘└┘└┘└──────────────────┘└───
doc        └──┘                 └┘               └─┘  └┘                     └───
txt        └──┘                 └┘               └─┘  └┘                     └───
par        └──┘                 └┘               └─┘  └┘                     └───
pid          └┘                 └┘               └─┘  └┘                     └───
st        └─────────────────────┘└────────────────────┘└──────────────────────┘└───
1380        degree_eq_nat_degree hq0, ← with_bot.coe_add, nat.sub_add_cancel hlt])
id         └──────────────────┘ └─┘    └──────────────┘  └────────────────┘ └─┘
src  ─────┘└──────────────────┘   └──┘└──────────────┘└┘└────────────────┘   
typ  ─────┘└──────────────────┘└─┘└──┘└──────────────┘└┘└────────────────┘└─┘
doc  ─────┘                       └──┘                └┘                     
txt  ─────┘                       └──┘                └┘                     
par  ─────┘                       └──┘                └┘                     
pid  ─────┘                       └──┘                └┘                     
st   ─────────────────────────────┘└──────────────────┘└──────────────────────┘
1381    h.2
id     
src     
typ    
1382    (by rw [leading_coeff_mul' hpq, leading_coeff_monomial, monic.def.1 hq, mul_one])
id             └────────────────┘ └─┘  └────────────────────┘  └───────┘   └┘  └─────┘
src        └──┘└────────────────┘   └┘└────────────────────┘└┘└───────┘└─┘  └┘└─────┘
typ        └──┘└────────────────┘└─┘└┘└────────────────────┘└┘└───────┘└─┘└┘└┘└─────┘
doc        └──┘                     └┘                      └┘         └─┘  └┘       
txt        └──┘                     └┘                      └┘         └─┘  └┘       
par        └──┘                     └┘                      └┘         └─┘  └┘       
pid          └┘                     └┘                      └┘         └─┘  └┘       
st        └─────────────────────────┘└──────────────────────┘└──────────────┘└───────┘
1383  
1384  noncomputable def div_mod_by_monic_aux : Π (p : polynomial α) {q : polynomial α},
id                                                  └────────┘        └────────┘ 
src                                                  └────────┘         └────────┘
typ                                                 └────────┘        └────────┘ 
doc                                                  └────────┘         └────────┘
1385    monic q → polynomial α × polynomial α
id     └───┘    └────────┘   └────────┘ 
src    └───┘     └────────┘    └────────┘
typ    └───┘    └────────┘   └────────┘ 
doc    └───┘     └────────┘     └────────┘
1386  | p := λ q hq, if h : degree q ≤ degree p ∧ p ≠ 0 then
id            └┘  └┘     └────┘   └────┘      
src                 └┘     └────┘    └────┘      
typ           └┘  └┘     └────┘   └────┘      
doc                        └────┘     └────┘
1387    let z := C (leading_coeff p) * X^(nat_degree p - nat_degree q)  in
id               └───────────┘      └────────┘    └────────┘ 
src               └───────────┘      └────────┘    └────────┘
typ              └───────────┘      └────────┘    └────────┘ 
doc               └───────────┘        └────────┘     └────────┘
1388    have wf : _ := div_wf_lemma h hq,
id                    └──────────┘  └┘
src                   └──────────┘
typ                   └──────────┘  └┘
1389    let dm := div_mod_by_monic_aux (p - z * q) hq in
id         └┘    └──────────────────┘         └┘
src                                         
typ        └┘    └──────────────────┘         └┘
1390    ⟨z + dm.1, dm.2⟩
id        └┘   └┘
src               
typ       └┘   └┘
1391    else ⟨0, p⟩
id          
typ         
1392  using_well_founded {dec_tac := tactic.assumption}
id                                  └───────────────┘
src                                 └───────────────┘
typ                                 └───────────────┘
1393  
1394  /-- `div_by_monic` gives the quotient of `p` by a monic polynomial `q`. -/
1395  def div_by_monic (p q : polynomial α) : polynomial α :=
id                           └────────┘     └────────┘ 
src                          └────────┘      └────────┘
typ                          └────────┘     └────────┘ 
doc                          └────────┘      └────────┘
1396  if hq : monic q then (div_mod_by_monic_aux p hq).1 else 0
id   └┘      └───┘        └──────────────────┘  └┘        
src  └┘      └───┘         └──────────────────┘      
typ  └┘      └───┘        └──────────────────┘  └┘        
doc          └───┘
1397  
1398  /-- `mod_by_monic` gives the remainder of `p` by a monic polynomial `q`. -/
1399  def mod_by_monic (p q : polynomial α) : polynomial α :=
id                           └────────┘     └────────┘ 
src                          └────────┘      └────────┘
typ                          └────────┘     └────────┘ 
doc                          └────────┘      └────────┘
1400  if hq : monic q then (div_mod_by_monic_aux p hq).2 else p
id   └┘      └───┘        └──────────────────┘  └┘        
src  └┘      └───┘         └──────────────────┘      
typ  └┘      └───┘        └──────────────────┘  └┘        
doc          └───┘
1401  
1402  infixl  ` /ₘ ` : 70 := div_by_monic
id                          └──────────┘
src                         └──────────┘
typ                         └──────────┘
doc                         └──────────┘
1403  
1404  infixl ` %ₘ ` : 70 := mod_by_monic
id                         └──────────┘
src                        └──────────┘
typ                        └──────────┘
doc                        └──────────┘
1405  
1406  lemma degree_mod_by_monic_lt : ∀ (p : polynomial α) {q : polynomial α} (hq : monic q)
id                                        └────────┘        └────────┘         └───┘ 
src                                        └────────┘         └────────┘          └───┘
typ                                       └────────┘        └────────┘         └───┘ 
doc                                        └────────┘         └────────┘          └───┘
1407    (hq0 : q ≠ 0), degree (p %ₘ q) < degree q
id                  └────┘   └┘    └────┘ 
src                  └────┘    └┘     └────┘
typ                 └────┘   └┘    └────┘ 
doc                   └────┘    └┘      └────┘
1408  | p := λ q hq hq0,
id            └┘ └─┘
typ           └┘ └─┘
1409  if h : degree q ≤ degree p ∧ p ≠ 0 then
id   └┘     └────┘   └────┘      
src  └┘     └────┘    └────┘      
typ  └┘     └────┘   └────┘      
doc         └────┘     └────┘
1410    have wf : _ := div_wf_lemma ⟨h.1, h.2⟩ hq,
id                    └──────────┘        └┘
src                   └──────────┘       
typ                   └──────────┘        └┘
1411    have degree ((p - C (leading_coeff p) * X ^ (nat_degree p - nat_degree q) * q) %ₘ q) < degree q :=
id          └────┘        └───────────┘        └────────┘    └────────┘      └┘    └────┘ 
src         └────┘        └───────────┘        └────────┘    └────────┘        └┘     └────┘
typ         └────┘        └───────────┘        └────────┘    └────────┘      └┘    └────┘ 
doc         └────┘         └───────────┘          └────────┘     └────────┘         └┘      └────┘
1412        degree_mod_by_monic_lt (p - C (leading_coeff p) * X ^ (nat_degree p - nat_degree q) * q)
id         └────────────────────┘       └───────────┘        └────────┘    └────────┘    
src                                     └───────────┘        └────────┘    └────────┘    
typ        └────────────────────┘       └───────────┘        └────────┘    └────────┘    
doc                                      └───────────┘          └────────┘     └────────┘
1413        hq hq0,
id         └┘ └─┘
typ        └┘ └─┘
1414    begin
st     └─────
1415      unfold mod_by_monic at this ⊢,
src      └───────────────────────────┘
typ      └───────────────────────────┘
doc      └───────────────────────────┘
txt      └───────────────────────────┘
par      └───────────────────────────┘
pid            └───────────┘└────────┘
st   ────────────────────────────────┘└─
1416      unfold div_mod_by_monic_aux,
src      └─────────────────────────┘
typ      └─────────────────────────┘
doc      └─────────────────────────┘
txt      └─────────────────────────┘
par      └─────────────────────────┘
pid            └───────────────────┘
st   ──────────────────────────────┘└─
1417      rw dif_pos hq at this ⊢,
id          └─────┘ └┘
src      └─┘└─────┘  └────────┘
typ      └─┘└─────┘└┘└────────┘
doc      └─┘         └────────┘
txt      └─┘         └────────┘
par      └─┘         └────────┘
pid                 └────────┘
st   ──────────────────────────┘└─
1418      rw if_pos h,
id          └────┘ 
src      └─┘└────┘
typ      └─┘└────┘
doc      └─┘      
txt      └─┘      
par      └─┘      
pid              
st   ──────────────┘└─
1419      exact this
id             └──┘
src      └────┘    
typ      └────┘└──┘
doc      └────┘    
txt      └────┘    
par      └────┘    
pid               
st   ───────────────
1420    end
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘└─┘
1421  else
1422    or.cases_on (not_and_distrib.1 h) begin
id     └─────────┘  └─────────────┘  
src    └─────────┘  └─────────────┘
typ    └─────────┘  └─────────────┘  
st                                       └─────
1423      unfold mod_by_monic div_mod_by_monic_aux,
src      └──────────────────────────────────────┘
typ      └──────────────────────────────────────┘
doc      └──────────────────────────────────────┘
txt      └──────────────────────────────────────┘
par      └──────────────────────────────────────┘
pid            └────────────────────────────────┘
st   ───────────────────────────────────────────┘└─
1424      rw [dif_pos hq, if_neg h],
id           └─────┘ └┘  └────┘ 
src      └──┘└─────┘  └┘└────┘ 
typ      └──┘└─────┘└┘└┘└────┘
doc      └──┘         └┘       
txt      └──┘         └┘       
par      └──┘         └┘       
pid        └┘         └┘       
st   ─────────────────┘└────────┘└──
1425      exact lt_of_not_ge,
id             └──────────┘
src      └────┘└──────────┘
typ      └────┘└──────────┘
doc      └────┘
txt      └────┘
par      └────┘
pid           
st   ─────────────────────┘└─
1426    end
st   ────┘
1427    begin
st     └─────
1428      assume hp,
src      └───────┘
typ      └───────┘
doc      └───────┘
txt      └───────┘
par      └───────┘
pid      └───────┘
st   ────────────┘└─
1429      unfold mod_by_monic div_mod_by_monic_aux,
src      └──────────────────────────────────────┘
typ      └──────────────────────────────────────┘
doc      └──────────────────────────────────────┘
txt      └──────────────────────────────────────┘
par      └──────────────────────────────────────┘
pid            └────────────────────────────────┘
st   ───────────────────────────────────────────┘└─
1430      rw [dif_pos hq, if_neg h, not_not.1 hp],
id           └─────┘ └┘  └────┘   └─────┘   └┘
src      └──┘└─────┘  └┘└────┘ └┘└─────┘└─┘  
typ      └──┘└─────┘└┘└┘└────┘└┘└─────┘└─┘└┘
doc      └──┘         └┘       └┘       └─┘  
txt      └──┘         └┘       └┘       └─┘  
par      └──┘         └┘       └┘       └─┘  
pid        └┘         └┘       └┘       └─┘  
st   ─────────────────┘└────────┘└────────────┘└──
1431      exact lt_of_le_of_ne bot_le
id             └────────────┘ └────┘
src      └────┘└────────────┘└────┘
typ      └────┘└────────────┘└────┘
doc      └────┘                    
txt      └────┘                    
par      └────┘                    
pid                               
st   ────────────────────────────────
1432        (ne.symm (mt degree_eq_bot.1 hq0)),
id          └─────┘  └┘ └───────────┘   └─┘
src  ─────┘ └─────┘ └┘└───────────┘└─┘   └┘
typ  ─────┘ └─────┘ └┘└───────────┘└─┘└─┘└┘
doc  ─────┘                        └─┘   └┘
txt  ─────┘                        └─┘   └┘
par  ─────┘                        └─┘   └┘
pid  ─────┘                        └─┘   └┘
st   ───────────────────────────────────────┘└─
1433    end
st   ────┘
1434  using_well_founded {dec_tac := tactic.assumption}
id                                  └───────────────┘
src                                 └───────────────┘
typ                                 └───────────────┘
1435  
1436  lemma mod_by_monic_eq_sub_mul_div : ∀ (p : polynomial α) {q : polynomial α} (hq : monic q),
id                                             └────────┘        └────────┘         └───┘ 
src                                             └────────┘         └────────┘          └───┘
typ                                            └────────┘        └────────┘         └───┘ 
doc                                             └────────┘         └────────┘          └───┘
1437    p %ₘ q = p - q * (p /ₘ q)
id      └┘         └┘ 
src      └┘             └┘
typ     └┘         └┘ 
doc      └┘                └┘
1438  | p := λ q hq,
id            └┘
typ           └┘
1439    if h : degree q ≤ degree p ∧ p ≠ 0 then
id     └┘     └────┘   └────┘      
src    └┘     └────┘    └────┘      
typ    └┘     └────┘   └────┘      
doc           └────┘     └────┘
1440      have wf : _ := div_wf_lemma h hq,
id                      └──────────┘  └┘
src                     └──────────┘
typ                     └──────────┘  └┘
1441      have ih : _ := mod_by_monic_eq_sub_mul_div
id                      └─────────────────────────┘
typ                     └─────────────────────────┘
1442        (p - C (leading_coeff p) * X ^ (nat_degree p - nat_degree q) * q) hq,
id               └───────────┘        └────────┘    └────────┘      └┘
src              └───────────┘        └────────┘    └────────┘    
typ              └───────────┘        └────────┘    └────────┘      └┘
doc               └───────────┘          └────────┘     └────────┘
1443      begin
st       └─────
1444        unfold mod_by_monic div_by_monic div_mod_by_monic_aux,
src        └───────────────────────────────────────────────────┘
typ        └───────────────────────────────────────────────────┘
doc        └───────────────────────────────────────────────────┘
txt        └───────────────────────────────────────────────────┘
par        └───────────────────────────────────────────────────┘
pid              └─────────────────────────────────────────────┘
st   ──────────────────────────────────────────────────────────┘└─
1445        rw [dif_pos hq, if_pos h],
id             └─────┘ └┘  └────┘ 
src        └──┘└─────┘  └┘└────┘ 
typ        └──┘└─────┘└┘└┘└────┘
doc        └──┘         └┘       
txt        └──┘         └┘       
par        └──┘         └┘       
pid          └┘         └┘       
st   ───────────────────┘└────────┘└──
1446        rw [mod_by_monic, dif_pos hq] at ih,
id             └──────────┘  └─────┘ └┘
src        └──┘└──────────┘└┘└─────┘  └─────┘
typ        └──┘└──────────┘└┘└─────┘└┘└─────┘
doc        └──┘└──────────┘└┘         └─────┘
txt        └──┘            └┘         └─────┘
par        └──┘            └┘         └─────┘
pid          └┘            └┘         └────┘
st   ─────────────────────┘└──────────┘└────┘└─
1447        refine ih.trans _,
id                └──────┘
src        └─────┘└──────┘└┘
typ        └─────┘└──────┘└┘
doc        └─────┘        └┘
txt        └─────┘        └┘
par        └─────┘        └┘
pid                      └┘
st   ──────────────────────┘└─
1448        unfold div_by_monic,
src        └─────────────────┘
typ        └─────────────────┘
doc        └─────────────────┘
txt        └─────────────────┘
par        └─────────────────┘
pid              └───────────┘
st   ────────────────────────┘└─
1449        rw [dif_pos hq, dif_pos hq, if_pos h, mul_add, sub_add_eq_sub_sub, mul_comm]
id             └─────┘ └┘  └─────┘ └┘  └────┘   └─────┘  └────────────────┘  └──────┘
src        └──┘└─────┘  └┘└─────┘  └┘└────┘ └┘└─────┘└┘└────────────────┘└┘└──────┘└─
typ        └──┘└─────┘└┘└┘└─────┘└┘└┘└────┘└┘└─────┘└┘└────────────────┘└┘└──────┘└─
doc        └──┘         └┘         └┘       └┘       └┘                  └┘        └─
txt        └──┘         └┘         └┘       └┘       └┘                  └┘        └─
par        └──┘         └┘         └┘       └┘       └┘                  └┘        └─
pid          └┘         └┘         └┘       └┘       └┘                  └┘        
st   ───────────────────┘└──────────┘└────────┘└───────┘└──────────────────┘└────────┘
1450      end
src  ───┘
typ  ───┘
doc  ───┘
txt  ───┘
par  ───┘
pid  ───┘
st   ───┘└─┘
1451    else
1452      begin
st       └─────
1453        unfold mod_by_monic div_by_monic div_mod_by_monic_aux,
src        └───────────────────────────────────────────────────┘
typ        └───────────────────────────────────────────────────┘
doc        └───────────────────────────────────────────────────┘
txt        └───────────────────────────────────────────────────┘
par        └───────────────────────────────────────────────────┘
pid              └─────────────────────────────────────────────┘
st   ──────────────────────────────────────────────────────────┘└─
1454        rw [dif_pos hq, if_neg h, dif_pos hq, if_neg h, mul_zero, sub_zero]
id             └─────┘ └┘  └────┘   └─────┘ └┘  └────┘   └──────┘  └──────┘
src        └──┘└─────┘  └┘└────┘ └┘└─────┘  └┘└────┘ └┘└──────┘└┘└──────┘└─
typ        └──┘└─────┘└┘└┘└────┘└┘└─────┘└┘└┘└────┘└┘└──────┘└┘└──────┘└─
doc        └──┘         └┘       └┘         └┘       └┘        └┘        └─
txt        └──┘         └┘       └┘         └┘       └┘        └┘        └─
par        └──┘         └┘       └┘         └┘       └┘        └┘        └─
pid          └┘         └┘       └┘         └┘       └┘        └┘        
st   ───────────────────┘└────────┘└──────────┘└────────┘└────────┘└────────┘
1455      end
id       └─┘
src  ───┘
typ  ───┘└─┘
doc  ───┘
txt  ───┘
par  ───┘
pid  ───┘
st   ───┘└─┘
1456  using_well_founded {dec_tac := tactic.assumption}
id                                  └───────────────┘
src                                 └───────────────┘
typ                                 └───────────────┘
1457  
1458  lemma mod_by_monic_add_div (p : polynomial α) {q : polynomial α} (hq : monic q) :
id                                   └────────┘        └────────┘         └───┘ 
src                                  └────────┘         └────────┘          └───┘
typ                                  └────────┘        └────────┘         └───┘ 
doc                                  └────────┘         └────────┘          └───┘
1459    p %ₘ q + q * (p /ₘ q) = p := eq_sub_iff_add_eq.1 (mod_by_monic_eq_sub_mul_div p hq)
id      └┘       └┘        └───────────────┘   └─────────────────────────┘  └┘
src      └┘          └┘          └───────────────┘   └─────────────────────────┘
typ     └┘       └┘        └───────────────┘   └─────────────────────────┘  └┘
doc      └┘            └┘
1460  
1461  @[simp] lemma zero_mod_by_monic (p : polynomial α) : 0 %ₘ p = 0 :=
id                                        └────────┘       └┘  
src                                       └────────┘        └┘   
typ                                       └────────┘       └┘  
doc    └──┘                               └────────┘        └┘
1462  begin
st   └─────
1463    unfold mod_by_monic div_mod_by_monic_aux,
src    └──────────────────────────────────────┘
typ    └──────────────────────────────────────┘
doc    └──────────────────────────────────────┘
txt    └──────────────────────────────────────┘
par    └──────────────────────────────────────┘
pid          └────────────────────────────────┘
st   ─────────────────────────────────────────┘└─
1464    by_cases hp : monic p,
id                   └───┘ 
src    └───────┘  └─┘└───┘
typ    └───────┘  └─┘└───┘
doc    └───────┘  └─┘└───┘
txt    └───────┘  └─┘     
par    └───────┘  └─┘     
pid              └─┘     
st   ──────────────────────┘└─
1465    { rw [dif_pos hp, if_neg (mt and.right (not_not_intro rfl))] },
id           └─────┘ └┘  └────┘  └┘ └───────┘  └───────────┘ └─┘
src      └──┘└─────┘  └┘└────┘ └┘└───────┘ └───────────┘└─┘└──┘
typ      └──┘└─────┘└┘└┘└────┘ └┘└───────┘ └───────────┘└─┘└──┘
doc      └──┘         └┘                                   └──┘
txt      └──┘         └┘                                   └──┘
par      └──┘         └┘                                   └──┘
pid        └┘         └┘                                   └─┘
st   ───┘└────────────┘└─────────────────────────────────────────┘└┘
1466    { rw [dif_neg hp] }
id           └─────┘ └┘
src      └──┘└─────┘  └┘
typ      └──┘└─────┘└┘└┘
doc      └──┘         └┘
txt      └──┘         └┘
par      └──┘         └┘
pid        └┘         
st   ─────────────────┘└─
1467  end
st   ──┘
1468  
1469  @[simp] lemma zero_div_by_monic (p : polynomial α) : 0 /ₘ p = 0 :=
id                                        └────────┘       └┘  
src                                       └────────┘        └┘   
typ                                       └────────┘       └┘  
doc    └──┘                               └────────┘        └┘
1470  begin
st   └─────
1471    unfold div_by_monic div_mod_by_monic_aux,
src    └──────────────────────────────────────┘
typ    └──────────────────────────────────────┘
doc    └──────────────────────────────────────┘
txt    └──────────────────────────────────────┘
par    └──────────────────────────────────────┘
pid          └────────────────────────────────┘
st   ─────────────────────────────────────────┘└─
1472    by_cases hp : monic p,
id                   └───┘ 
src    └───────┘  └─┘└───┘
typ    └───────┘  └─┘└───┘
doc    └───────┘  └─┘└───┘
txt    └───────┘  └─┘     
par    └───────┘  └─┘     
pid              └─┘     
st   ──────────────────────┘└─
1473    { rw [dif_pos hp, if_neg (mt and.right (not_not_intro rfl))] },
id           └─────┘ └┘  └────┘  └┘ └───────┘  └───────────┘ └─┘
src      └──┘└─────┘  └┘└────┘ └┘└───────┘ └───────────┘└─┘└──┘
typ      └──┘└─────┘└┘└┘└────┘ └┘└───────┘ └───────────┘└─┘└──┘
doc      └──┘         └┘                                   └──┘
txt      └──┘         └┘                                   └──┘
par      └──┘         └┘                                   └──┘
pid        └┘         └┘                                   └─┘
st   ───┘└────────────┘└─────────────────────────────────────────┘└┘
1474    { rw [dif_neg hp] }
id           └─────┘ └┘
src      └──┘└─────┘  └┘
typ      └──┘└─────┘└┘└┘
doc      └──┘         └┘
txt      └──┘         └┘
par      └──┘         └┘
pid        └┘         
st   ─────────────────┘└─
1475  end
st   ──┘
1476  
1477  @[simp] lemma mod_by_monic_zero (p : polynomial α) : p %ₘ 0 = p :=
id                                        └────────┘      └┘    
src                                       └────────┘        └┘   
typ                                       └────────┘      └┘    
doc    └──┘                               └────────┘        └┘
1478  if h : monic (0 : polynomial α) then (subsingleton_of_monic_zero h).1 _ _ else
id   └┘     └───┘      └────────┘         └────────────────────────┘  
src  └┘     └───┘      └────────┘          └────────────────────────┘   
typ  └┘     └───┘      └────────┘         └────────────────────────┘  
doc         └───┘      └────────┘
1479  by unfold mod_by_monic div_mod_by_monic_aux; rw dif_neg h
id                                                   └─────┘ 
src     └──────────────────────────────────────┘  └─┘└─────┘ 
typ     └──────────────────────────────────────┘  └─┘└─────┘
doc     └──────────────────────────────────────┘  └─┘        
txt     └──────────────────────────────────────┘  └─┘        
par     └──────────────────────────────────────┘  └─┘        
pid           └────────────────────────────────┘            
st     └────────────────────────────────────────────┘└─────┘└──
1480  
src  
typ  
doc  
txt  
par  
pid  
st   
1481  @[simp] lemma div_by_monic_zero (p : polynomial α) : p /ₘ 0 = 0 :=
id                                        └────────┘      └┘   
src                                       └────────┘        └┘   
typ                                       └────────┘      └┘   
doc    └──┘                               └────────┘        └┘
1482  if h : monic (0 : polynomial α) then (subsingleton_of_monic_zero h).1 _ _ else
id   └┘     └───┘      └────────┘         └────────────────────────┘  
src  └┘     └───┘      └────────┘          └────────────────────────┘   
typ  └┘     └───┘      └────────┘         └────────────────────────┘  
doc         └───┘      └────────┘
1483  by unfold div_by_monic div_mod_by_monic_aux; rw dif_neg h
id                                                   └─────┘ 
src     └──────────────────────────────────────┘  └─┘└─────┘ 
typ     └──────────────────────────────────────┘  └─┘└─────┘
doc     └──────────────────────────────────────┘  └─┘        
txt     └──────────────────────────────────────┘  └─┘        
par     └──────────────────────────────────────┘  └─┘        
pid           └────────────────────────────────┘            
st     └────────────────────────────────────────────┘└─────┘└──
1484  
src  
typ  
doc  
txt  
par  
pid  
st   
1485  lemma div_by_monic_eq_of_not_monic (p : polynomial α) (hq : ¬monic q) : p /ₘ q = 0 := dif_neg hq
id                                           └────────┘         └───┘      └┘        └─────┘ └┘
src                                          └────────┘          └───┘        └┘         └─────┘
typ                                          └────────┘         └───┘      └┘        └─────┘ └┘
doc                                          └────────┘           └───┘        └┘
1486  
1487  lemma mod_by_monic_eq_of_not_monic (p : polynomial α) (hq : ¬monic q) : p %ₘ q = p := dif_neg hq
id                                           └────────┘         └───┘      └┘       └─────┘ └┘
src                                          └────────┘          └───┘        └┘         └─────┘
typ                                          └────────┘         └───┘      └┘       └─────┘ └┘
doc                                          └────────┘           └───┘        └┘
1488  
1489  lemma mod_by_monic_eq_self_iff (hq : monic q) (hq0 : q ≠ 0) : p %ₘ q = p ↔ degree p < degree q :=
id                                        └───┘                  └┘     └────┘   └────┘ 
src                                       └───┘                     └┘       └────┘    └────┘
typ                                       └───┘                  └┘     └────┘   └────┘ 
doc                                       └───┘                      └┘         └────┘     └────┘
1490  ⟨λ h, h ▸ degree_mod_by_monic_lt _ hq hq0,
id          └────────────────────┘   └┘ └─┘
src           └────────────────────┘
typ         └────────────────────┘   └┘ └─┘
1491  λ h, have ¬ degree q ≤ degree p := not_le_of_gt h,
id             └────┘   └────┘     └──────────┘ 
src             └────┘    └────┘      └──────────┘
typ            └────┘   └────┘     └──────────┘ 
doc              └────┘     └────┘
1492    by unfold mod_by_monic div_mod_by_monic_aux; rw [dif_pos hq, if_neg (mt and.left this)]⟩
id                                                      └─────┘ └┘  └────┘  └┘ └──────┘ └──┘
src       └──────────────────────────────────────┘  └──┘└─────┘  └┘└────┘ └┘└──────┘    └┘
typ       └──────────────────────────────────────┘  └──┘└─────┘└┘└┘└────┘ └┘└──────┘└──┘└┘
doc       └──────────────────────────────────────┘  └──┘         └┘                     └┘
txt       └──────────────────────────────────────┘  └──┘         └┘                     └┘
par       └──────────────────────────────────────┘  └──┘         └┘                     └┘
pid             └────────────────────────────────┘    └┘         └┘                     └┘
st       └─────────────────────────────────────────────┘└────────┘└─────────────────────────┘
1493  
1494  lemma div_by_monic_eq_zero_iff (hq : monic q) (hq0 : q ≠ 0) : p /ₘ q = 0 ↔ degree p < degree q :=
id                                        └───┘                  └┘      └────┘   └────┘ 
src                                       └───┘                     └┘       └────┘    └────┘
typ                                       └───┘                  └┘      └────┘   └────┘ 
doc                                       └───┘                      └┘         └────┘     └────┘
1495  ⟨λ h, by have := mod_by_monic_add_div p hq;
id                   └──────────────────┘  └┘
src           └──────┘└──────────────────┘ 
typ          └──────┘└──────────────────┘└┘
doc           └──────┘                     
txt           └──────┘                     
par           └──────┘                     
pid           └───┘└─┘                     
st           └───────────────────────────────────
1496    rwa [h, mul_zero, add_zero, mod_by_monic_eq_self_iff hq hq0] at this,
id            └──────┘  └──────┘  └──────────────────────┘ └┘ └─┘
src    └───┘ └┘└──────┘└┘└──────┘└┘└──────────────────────┘     └───────┘
typ    └───┘└┘└──────┘└┘└──────┘└┘└──────────────────────┘└┘└─┘└───────┘
doc    └───┘ └┘        └┘        └┘                             └───────┘
txt    └───┘ └┘        └┘        └┘                             └───────┘
par    └───┘ └┘        └┘        └┘                             └───────┘
pid       └┘ └┘        └┘        └┘                             └──────┘
st   ──────┘└────────┘└────────┘└───────────────────────────────┘└──────┘
1497  λ h, have ¬ degree q ≤ degree p := not_le_of_gt h,
id             └────┘   └────┘     └──────────┘ 
src             └────┘    └────┘      └──────────┘
typ            └────┘   └────┘     └──────────┘ 
doc              └────┘     └────┘
1498    by unfold div_by_monic div_mod_by_monic_aux; rw [dif_pos hq, if_neg (mt and.left this)]⟩
id                                                      └─────┘ └┘  └────┘  └┘ └──────┘ └──┘
src       └──────────────────────────────────────┘  └──┘└─────┘  └┘└────┘ └┘└──────┘    └┘
typ       └──────────────────────────────────────┘  └──┘└─────┘└┘└┘└────┘ └┘└──────┘└──┘└┘
doc       └──────────────────────────────────────┘  └──┘         └┘                     └┘
txt       └──────────────────────────────────────┘  └──┘         └┘                     └┘
par       └──────────────────────────────────────┘  └──┘         └┘                     └┘
pid             └────────────────────────────────┘    └┘         └┘                     └┘
st       └─────────────────────────────────────────────┘└────────┘└─────────────────────────┘
1499  
1500  lemma degree_add_div_by_monic (hq : monic q) (h : degree q ≤ degree p) :
id                                       └───┘        └────┘   └────┘ 
src                                      └───┘         └────┘    └────┘
typ                                      └───┘        └────┘   └────┘ 
doc                                      └───┘         └────┘     └────┘
1501    degree q + degree (p /ₘ q) = degree p :=
id     └────┘   └────┘   └┘    └────┘ 
src    └────┘    └────┘    └┘     └────┘
typ    └────┘   └────┘   └┘    └────┘ 
doc    └────┘     └────┘    └┘      └────┘
1502  if hq0 : q = 0 then
id   └┘        
src  └┘         
typ  └┘        
1503    have ∀ (p : polynomial α), p = 0,
id                 └────────┘     
src                └────────┘       
typ                └────────┘     
doc                └────────┘
1504      from λ p, (@subsingleton_of_monic_zero α _ (hq0 ▸ hq)).1 _ _,
id                  └────────────────────────┘     └─┘  └┘  
src                  └────────────────────────┘               
typ                 └────────────────────────┘     └─┘  └┘  
1505    by rw [this (p /ₘ q), this p, this q]; refl
id            └──┘   └┘    └──┘   └──┘ 
src       └──┘      └┘ └─┘     └┘       └───┘
typ       └──┘└──┘ └┘└─┘└──┘└┘└──┘  └───┘
doc       └──┘      └┘ └─┘     └┘       └───┘
txt       └──┘         └─┘     └┘       └───┘
par       └──┘         └─┘     └┘       └───┘
pid         └┘         └─┘     └┘           
st       └────────────────┘└──────┘└──────┘└─────┘
1506  else
1507  have hdiv0 : p /ₘ q ≠ 0 := by rwa [(≠), div_by_monic_eq_zero_iff hq hq0, not_lt],
id   └──┘          └┘                    └──────────────────────┘ └┘ └─┘  └────┘
src                 └┘            └───┘└──┘└──────────────────────┘     └┘└────┘
typ  └──┘          └┘           └───┘└──┘└──────────────────────┘└┘└─┘└┘└────┘
doc                 └┘             └───┘ └──┘                             └┘      
txt                                └───┘ └──┘                             └┘      
par                                └───┘ └──┘                             └┘      
pid                                   └┘ └──┘                             └┘      
st                                └───────┘└───────────────────────────────┘└──────┘
1508  have hlc : leading_coeff q * leading_coeff (p /ₘ q) ≠ 0 :=
id              └───────────┘   └───────────┘   └┘   
src             └───────────┘    └───────────┘    └┘    
typ             └───────────┘   └───────────┘   └┘   
doc             └───────────┘     └───────────┘    └┘
1509    by rwa [monic.def.1 hq, one_mul, (≠), leading_coeff_eq_zero],
id             └───────┘   └┘  └─────┘      └───────────────────┘
src       └───┘└───────┘└─┘  └┘└─────┘└┘└──┘└───────────────────┘
typ       └───┘└───────┘└─┘└┘└┘└─────┘└┘└──┘└───────────────────┘
doc       └───┘         └─┘  └┘       └┘ └──┘                     
txt       └───┘         └─┘  └┘       └┘ └──┘                     
par       └───┘         └─┘  └┘       └┘ └──┘                     
pid          └┘         └─┘  └┘       └┘ └──┘                     
st       └──────────────────┘└───────┘└───┘└─────────────────────┘
1510  have hmod : degree (p %ₘ q) < degree (q * (p /ₘ q)) :=
id               └────┘   └┘    └────┘      └┘ 
src              └────┘    └┘     └────┘        └┘
typ              └────┘   └┘    └────┘      └┘ 
doc              └────┘    └┘      └────┘         └┘
1511    calc degree (p %ₘ q) < degree q : degree_mod_by_monic_lt _ hq hq0
id          └────┘   └┘     └────┘    └────────────────────┘   └┘ └─┘
src         └────┘    └┘      └────┘     └────────────────────┘
typ         └────┘   └┘     └────┘    └────────────────────┘   └┘ └─┘
doc         └────┘    └┘      └────┘
1512    ... ≤ _ : by rw [degree_mul_eq' hlc, degree_eq_nat_degree hq0,
id                      └────────────┘ └─┘  └──────────────────┘ └─┘
src                 └──┘└────────────┘   └┘└──────────────────┘   └─
typ                 └──┘└────────────┘└─┘└┘└──────────────────┘└─┘└─
doc                 └──┘                 └┘                       └─
txt                 └──┘                 └┘                       └─
par                 └──┘                 └┘                       └─
pid                   └┘                 └┘                       └─
st                 └─────────────────────┘└────────────────────────┘└─
1513        degree_eq_nat_degree hdiv0, ← with_bot.coe_add, with_bot.coe_le_coe];
id         └──────────────────┘ └───┘    └──────────────┘  └─────────────────┘
src  ─────┘└──────────────────┘     └──┘└──────────────┘└┘└─────────────────┘
typ  ─────┘└──────────────────┘└───┘└──┘└──────────────┘└┘└─────────────────┘
doc  ─────┘                         └──┘                └┘                   
txt  ─────┘                         └──┘                └┘                   
par  ─────┘                         └──┘                └┘                   
pid  ─────┘                         └──┘                └┘                   
st   ───────────────────────────────┘└──────────────────┘└───────────────────┘└─
1514      exact nat.le_add_right _ _,
id             └──────────────┘
src      └────┘└──────────────┘└──┘
typ      └────┘└──────────────┘└──┘
doc      └────┘                └──┘
txt      └────┘                └──┘
par      └────┘                └──┘
pid                           └──┘
st   ─────────────────────────────┘
1515  calc degree q + degree (p /ₘ q) = degree (q * (p /ₘ q)) : eq.symm (degree_mul_eq' hlc)
id        └────┘   └────┘   └┘     └────┘      └┘      └─────┘  └────────────┘ └─┘
src       └────┘    └────┘    └┘      └────┘        └┘       └─────┘  └────────────┘
typ       └────┘   └────┘   └┘     └────┘      └┘      └─────┘  └────────────┘ └─┘
doc       └────┘     └────┘    └┘      └────┘         └┘
1516  ... = degree (p %ₘ q + q * (p /ₘ q)) : (degree_add_eq_of_degree_lt hmod).symm
id         └────┘   └┘       └┘       └────────────────────────┘ └──┘ └──┘
src        └────┘    └┘          └┘        └────────────────────────┘      └──┘
typ        └────┘   └┘       └┘       └────────────────────────┘ └──┘ └──┘
doc        └────┘    └┘            └┘
1517  ... = _ : congr_arg _ (mod_by_monic_add_div _ hq)
id             └───────┘    └──────────────────┘   └┘
src            └───────┘    └──────────────────┘
typ            └───────┘    └──────────────────┘   └┘
1518  
1519  lemma degree_div_by_monic_le (p q : polynomial α) : degree (p /ₘ q) ≤ degree p :=
id                                       └────────┘     └────┘   └┘    └────┘ 
src                                      └────────┘      └────┘    └┘     └────┘
typ                                      └────────┘     └────┘   └┘    └────┘ 
doc                                      └────────┘      └────┘    └┘      └────┘
1520  if hp0 : p = 0 then by simp only [hp0, zero_div_by_monic, le_refl]
id   └┘                              └─┘  └───────────────┘  └─────┘
src  └┘                    └─────────┘   └┘└───────────────┘└┘└─────┘└┘
typ  └┘                   └─────────┘└─┘└┘└───────────────┘└┘└─────┘└┘
doc                         └─────────┘   └┘                 └┘       └┘
txt                         └─────────┘   └┘                 └┘       └┘
par                         └─────────┘   └┘                 └┘       └┘
pid                             └──┘└┘   └┘                 └┘       
st                         └───────────────────────────────────────────┘
1521  else if hq : monic q then
id        └┘      └───┘ 
src       └┘      └───┘
typ       └┘      └───┘ 
doc               └───┘
1522    have hq0 : q ≠ 0 := ne_zero_of_ne_zero_of_monic hp0 hq,
id                       └─────────────────────────┘ └─┘ └┘
src                       └─────────────────────────┘
typ                      └─────────────────────────┘ └─┘ └┘
1523    if h : degree q ≤ degree p
id     └┘     └────┘   └────┘ 
src    └┘     └────┘    └────┘
typ    └┘     └────┘   └────┘ 
doc           └────┘     └────┘
1524    then by rw [← degree_add_div_by_monic hq h, degree_eq_nat_degree hq0,
id                   └─────────────────────┘ └┘   └──────────────────┘ └─┘
src            └────┘└─────────────────────┘   └┘└──────────────────┘   └─
typ            └────┘└─────────────────────┘└┘└┘└──────────────────┘└─┘└─
doc            └────┘                          └┘                       └─
txt            └────┘                          └┘                       └─
par            └────┘                          └┘                       └─
pid              └──┘                          └┘                       └─
st            └─────────────────────────────────┘└────────────────────────┘└─
1525        degree_eq_nat_degree (mt (div_by_monic_eq_zero_iff hq hq0).1 (not_lt.2 h))];
id         └──────────────────┘  └┘  └──────────────────────┘ └┘ └─┘     └────┘   
src  ─────┘└──────────────────┘ └┘ └──────────────────────┘     └──┘ └────┘└─┘ └─┘
typ  ─────┘└──────────────────┘ └┘ └──────────────────────┘└┘└─┘└──┘ └────┘└─┘└─┘
doc  ─────┘                                                     └──┘       └─┘ └─┘
txt  ─────┘                                                     └──┘       └─┘ └─┘
par  ─────┘                                                     └──┘       └─┘ └─┘
pid  ─────┘                                                     └──┘       └─┘ └─┘
st   ───────────────────────────────────────────────────────────────────────────────┘└─
1526      exact with_bot.coe_le_coe.2 (nat.le_add_left _ _)
id             └─────────────────┘    └─────────────┘
src      └────┘└─────────────────┘└─┘ └─────────────┘└─────
typ      └────┘└─────────────────┘└─┘ └─────────────┘└─────
doc      └────┘                   └─┘                └─────
txt      └────┘                   └─┘                └─────
par      └────┘                   └─┘                └─────
pid                              └─┘                └───┘
st   ──────────────────────────────────────────────────────
1527    else
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘
1528      by unfold div_by_monic div_mod_by_monic_aux;
src         └──────────────────────────────────────┘
typ         └──────────────────────────────────────┘
doc         └──────────────────────────────────────┘
txt         └──────────────────────────────────────┘
par         └──────────────────────────────────────┘
pid               └────────────────────────────────┘
st         └──────────────────────────────────────────
1529        simp only [dif_pos hq, h, false_and, if_false, degree_zero, bot_le]
id                    └─────┘ └┘    └───────┘  └──────┘  └─────────┘  └────┘
src        └─────────┘└─────┘  └┘ └┘└───────┘└┘└──────┘└┘└─────────┘└┘└────┘└┘
typ        └─────────┘└─────┘└┘└┘└┘└───────┘└┘└──────┘└┘└─────────┘└┘└────┘└┘
doc        └─────────┘         └┘ └┘         └┘        └┘           └┘      └┘
txt        └─────────┘         └┘ └┘         └┘        └┘           └┘      └┘
par        └─────────┘         └┘ └┘         └┘        └┘           └┘      └┘
pid            └──┘└┘         └┘ └┘         └┘        └┘           └┘      
st   ─────────────────────────────────────────────────────────────────────────┘
1530  else (div_by_monic_eq_of_not_monic p hq).symm ▸ bot_le
id         └──────────────────────────┘  └┘ └──┘   └────┘
src        └──────────────────────────┘      └──┘   └────┘
typ        └──────────────────────────┘  └┘ └──┘   └────┘
1531  
1532  lemma degree_div_by_monic_lt (p : polynomial α) {q : polynomial α} (hq : monic q)
id                                     └────────┘        └────────┘         └───┘ 
src                                    └────────┘         └────────┘          └───┘
typ                                    └────────┘        └────────┘         └───┘ 
doc                                    └────────┘         └────────┘          └───┘
1533    (hp0 : p ≠ 0) (h0q : 0 < degree q) : degree (p /ₘ q) < degree p :=
id                           └────┘     └────┘   └┘    └────┘ 
src                           └────┘      └────┘    └┘     └────┘
typ                          └────┘     └────┘   └┘    └────┘ 
doc                             └────┘      └────┘    └┘      └────┘
1534  have hq0 : q ≠ 0 := ne_zero_of_ne_zero_of_monic hp0 hq,
id                     └─────────────────────────┘ └─┘ └┘
src                     └─────────────────────────┘
typ                    └─────────────────────────┘ └─┘ └┘
1535  if hpq : degree p < degree q
id   └┘       └────┘   └────┘ 
src  └┘       └────┘    └────┘
typ  └┘       └────┘   └────┘ 
doc           └────┘     └────┘
1536  then begin
st        └─────
1537    rw [(div_by_monic_eq_zero_iff hq hq0).2 hpq, degree_eq_nat_degree hp0],
id          └──────────────────────┘ └┘ └─┘    └─┘  └──────────────────┘ └─┘
src    └──┘ └──────────────────────┘     └──┘   └┘└──────────────────┘   
typ    └──┘ └──────────────────────┘└┘└─┘└──┘└─┘└┘└──────────────────┘└─┘
doc    └──┘                              └──┘   └┘                       
txt    └──┘                              └──┘   └┘                       
par    └──┘                              └──┘   └┘                       
pid      └┘                              └──┘   └┘                       
st   ────────────────────────────────────────────┘└────────────────────────┘└──
1538    exact with_bot.bot_lt_some _
id           └──────────────────┘
src    └────┘└──────────────────┘└─┘
typ    └────┘└──────────────────┘└─┘
doc    └────┘                    └─┘
txt    └────┘                    └─┘
par    └────┘                    └─┘
pid                             └┘
st   ──────────────────────────────┘
1539  end
st   └─┘
1540  else begin
st        └─────
1541    rw [← degree_add_div_by_monic hq (not_lt.1 hpq), degree_eq_nat_degree hq0,
id           └─────────────────────┘ └┘  └────┘   └─┘   └──────────────────┘ └─┘
src    └────┘└─────────────────────┘   └────┘└─┘   └─┘└──────────────────┘   └─
typ    └────┘└─────────────────────┘└┘ └────┘└─┘└─┘└─┘└──────────────────┘└─┘└─
doc    └────┘                                └─┘   └─┘                       └─
txt    └────┘                                └─┘   └─┘                       └─
par    └────┘                                └─┘   └─┘                       └─
pid      └──┘                                └─┘   └─┘                       └─
st   ────────────────────────────────────────────────┘└────────────────────────┘└─
1542          degree_eq_nat_degree (mt (div_by_monic_eq_zero_iff hq hq0).1 hpq)],
id           └──────────────────┘  └┘  └──────────────────────┘ └┘ └─┘    └─┘
src  ───────┘└──────────────────┘ └┘ └──────────────────────┘     └──┘   └┘
typ  ───────┘└──────────────────┘ └┘ └──────────────────────┘└┘└─┘└──┘└─┘└┘
doc  ───────┘                                                     └──┘   └┘
txt  ───────┘                                                     └──┘   └┘
par  ───────┘                                                     └──┘   └┘
pid  ───────┘                                                     └──┘   └┘
st   ────────────────────────────────────────────────────────────────────────┘└──
1543    exact with_bot.coe_lt_coe.2 (nat.lt_add_of_pos_left
id                                  └────────────────────┘
src    └────┘                   └─┘ └────────────────────┘
typ    └────┘                   └─┘ └────────────────────┘
doc    └────┘                   └─┘                       
txt    └────┘                   └─┘                       
par    └────┘                   └─┘                       
pid                            └─┘                       
st   ──────────────────────────────────────────────────────
1544      (with_bot.coe_lt_coe.1 $ (degree_eq_nat_degree hq0) ▸ h0q))
id        └─────────────────┘      └──────────────────┘ └─┘   └─┘
src  ───┘ └─────────────────┘└─┘  └──────────────────┘   └┘   └─┘
typ  ───┘ └─────────────────┘└─┘  └──────────────────┘└─┘└┘└─┘└─┘
doc  ───┘                    └─┘                         └┘    └─┘
txt  ───┘                    └─┘                         └┘    └─┘
par  ───┘                    └─┘                         └┘    └─┘
pid  ───┘                    └─┘                         └┘    └┘
st   ───────────────────────────────────────────────────────────────┘
1545  end
id   └─┘
typ  └─┘
st   └─┘
1546  
1547  lemma div_mod_by_monic_unique {f g} (q r : polynomial α) (hg : monic g)
id                                              └────────┘         └───┘ 
src                                             └────────┘          └───┘
typ                                             └────────┘         └───┘ 
doc                                             └────────┘          └───┘
1548    (h : r + g * q = f ∧ degree r < degree g) : f /ₘ g = q ∧ f %ₘ g = r :=
id                  └────┘   └────┘      └┘      └┘   
src                     └────┘    └────┘        └┘         └┘   
typ                 └────┘   └────┘      └┘      └┘   
doc                         └────┘     └────┘        └┘           └┘
1549  if hg0 : g = 0 then by split; exact (subsingleton_of_monic_zero
id   └┘                                 └────────────────────────┘
src  └┘                    └───┘  └────┘ └────────────────────────┘
typ  └┘                   └───┘  └────┘ └────────────────────────┘
doc                         └───┘  └────┘                           
txt                         └───┘  └────┘                           
par                         └───┘  └────┘                           
pid                                                                
st                         └─────────────────────────────────────────
1550    (hg0 ▸ hg : monic (0 : polynomial α))).1 _ _
id      └─┘  └┘   └───┘      └────────┘ 
src  ─┘      └─┘└───┘ └──┘└────────┘ └────────┘
typ  ─┘ └─┘└┘└─┘└───┘ └──┘└────────┘└────────┘
doc  ─┘       └─┘└───┘ └──┘└────────┘ └────────┘
txt  ─┘       └─┘      └──┘           └────────┘
par  ─┘       └─┘      └──┘           └────────┘
pid  ─┘       └─┘      └──┘           └───────┘
st   ──────────────────────────────────────────────┘
1551  else
1552    have h₁ : r - f %ₘ g = -g * (q - f /ₘ g),
id     └──┘         └┘         └┘ 
src                   └┘             └┘
typ    └──┘         └┘         └┘ 
doc                    └┘                 └┘
1553      from eq_of_sub_eq_zero
id            └───────────────┘
src           └───────────────┘
typ           └───────────────┘
1554        (by rw [← sub_eq_zero_of_eq (h.1.trans (mod_by_monic_add_div f hg).symm)];
id                   └───────────────┘            └──────────────────┘  └┘
src            └────┘└───────────────┘  └───────┘ └──────────────────┘   └──────┘
typ            └────┘└───────────────┘ └───────┘ └──────────────────┘└┘└──────┘
doc            └────┘                   └───────┘                        └──────┘
txt            └────┘                   └───────┘                        └──────┘
par            └────┘                   └───────┘                        └──────┘
pid              └──┘                   └───────┘                        └──────┘
st            └───────────────────────────────────────────────────────────────────┘└─
1555          simp [mul_add, mul_comm]),
id                 └─────┘  └──────┘
src          └────┘└─────┘└┘└──────┘
typ          └────┘└─────┘└┘└──────┘
doc          └────┘       └┘        
txt          └────┘       └┘        
par          └────┘       └┘        
pid                     └┘        
st   ───────────────────────────────┘
1556    have h₂ : degree (r - f %ₘ g) = degree (g * (q - f /ₘ g)),
id               └────┘     └┘    └────┘        └┘ 
src              └────┘       └┘     └────┘           └┘
typ              └────┘     └┘    └────┘        └┘ 
doc              └────┘        └┘      └────┘             └┘
1557      by simp [h₁],
id                └┘
src         └────┘  
typ         └────┘└┘
doc         └────┘  
txt         └────┘  
par         └────┘  
pid               
st         └────────┘
1558    have h₄ : degree (r - f %ₘ g) < degree g,
id               └────┘     └┘    └────┘ 
src              └────┘       └┘     └────┘
typ              └────┘     └┘    └────┘ 
doc              └────┘        └┘      └────┘
1559      from calc degree (r - f %ₘ g) ≤ max (degree r) (degree (-(f %ₘ g))) :
id                 └────┘     └┘     └─┘  └────┘    └────┘    └┘ 
src                └────┘       └┘      └─┘  └────┘     └────┘     └┘
typ                └────┘     └┘     └─┘  └────┘    └────┘    └┘ 
doc                └────┘        └┘           └────┘     └────┘      └┘
1560        degree_add_le _ _
id         └───────────┘
src        └───────────┘
typ        └───────────┘
1561      ... < degree g : max_lt_iff.2 ⟨h.2, by rw degree_neg; exact degree_mod_by_monic_lt _ hg hg0⟩,
id             └────┘    └────────┘            └────────┘        └────────────────────┘   └┘ └─┘
src            └────┘     └────────┘          └─┘└────────┘  └────┘└────────────────────┘└─┘  
typ            └────┘    └────────┘         └─┘└────────┘  └────┘└────────────────────┘└─┘└┘└─┘
doc            └────┘                           └─┘            └────┘                      └─┘  
txt                                             └─┘            └────┘                      └─┘  
par                                             └─┘            └────┘                      └─┘  
pid                                                                                      └─┘  
st                                             └───────────────────────────────────────────────────┘
1562    have h₅ : q - (f /ₘ g) = 0,
id                   └┘   
src                    └┘    
typ                  └┘   
doc                     └┘
1563      from by_contradiction
id            └──────────────┘
src           └──────────────┘
typ           └──────────────┘
1564        (λ hqf, not_le_of_gt h₄ $
id            └─┘  └──────────┘ └┘
src                └──────────┘
typ           └─┘  └──────────┘ └┘
1565          calc degree g ≤ degree g + degree (q - f /ₘ g) :
id                └────┘    └────┘   └────┘     └┘ 
src               └────┘     └────┘    └────┘       └┘
typ               └────┘    └────┘   └────┘     └┘ 
doc               └────┘     └────┘     └────┘        └┘
1566            by erw [degree_eq_nat_degree hg0, degree_eq_nat_degree hqf,
id                     └──────────────────┘ └─┘  └──────────────────┘ └─┘
src               └───┘└──────────────────┘   └┘└──────────────────┘   └─
typ               └───┘└──────────────────┘└─┘└┘└──────────────────┘└─┘└─
doc               └───┘                       └┘                       └─
txt               └───┘                       └┘                       └─
par               └───┘                       └┘                       └─
pid                  └┘                       └┘                       └─
st               └────────────────────────────┘└────────────────────────┘└─
1567                with_bot.coe_le_coe];
id                 └─────────────────┘
src  ─────────────┘└─────────────────┘
typ  ─────────────┘└─────────────────┘
doc  ─────────────┘                   
txt  ─────────────┘                   
par  ─────────────┘                   
pid  ─────────────┘                   
st   ────────────────────────────────┘└─
1568              exact nat.le_add_right _ _
id                     └──────────────┘
src              └────┘└──────────────┘└────
typ              └────┘└──────────────┘└────
doc              └────┘                └────
txt              └────┘                └────
par              └────┘                └────
pid                                   └──┘
st   ───────────────────────────────────────
1569          ... = degree (r - f %ₘ g) :
id                 └────┘     └┘ 
src  ───────┘      └────┘       └┘
typ  ───────┘      └────┘     └┘ 
doc  ───────┘      └────┘        └┘
txt  ───────┘
par  ───────┘
pid  ───────┘
st   ───────┘
1570            by rw [h₂, degree_mul_eq']; simpa [monic.def.1 hg]),
id                    └┘  └────────────┘          └───────┘   └┘
src               └──┘  └┘└────────────┘  └─────┘└───────┘└─┘  
typ               └──┘└┘└┘└────────────┘  └─────┘└───────┘└─┘└┘
doc               └──┘  └┘                └─────┘         └─┘  
txt               └──┘  └┘                └─────┘         └─┘  
par               └──┘  └┘                └─────┘         └─┘  
pid                 └┘  └┘                              └─┘  
st               └─────┘└──────────────┘└──────────────────────┘
1571    ⟨eq.symm $ eq_of_sub_eq_zero h₅,
id      └─────┘   └───────────────┘ └┘
src     └─────┘   └───────────────┘
typ     └─────┘   └───────────────┘ └┘
1572      eq.symm $ eq_of_sub_eq_zero $ by simpa [h₅] using h₁⟩
id       └─────┘   └───────────────┘             └┘        └┘
src      └─────┘   └───────────────┘      └─────┘  └──────┘
typ      └─────┘   └───────────────┘      └─────┘└┘└──────┘└┘
doc                                       └─────┘  └──────┘
txt                                       └─────┘  └──────┘
par                                       └─────┘  └──────┘
pid                                              └────┘
st                                       └──────────────────┘
1573  
1574  lemma map_mod_div_by_monic [comm_ring β] (f : α → β) [is_semiring_hom f] (hq : monic q) :
id                               └───────┘              └─────────────┘         └───┘ 
src                              └───────┘                 └─────────────┘          └───┘
typ                              └───────┘              └─────────────┘         └───┘ 
doc                                                        └─────────────┘          └───┘
1575    (p /ₘ q).map f = p.map f /ₘ q.map f ∧ (p %ₘ q).map f = p.map f %ₘ q.map f :=
id       └┘  └─┘    └──┘  └┘ └──┘     └┘  └─┘    └──┘  └┘ └──┘ 
src       └┘   └─┘      └──┘   └┘  └──┘       └┘   └─┘      └──┘   └┘  └──┘
typ      └┘  └─┘    └──┘  └┘ └──┘     └┘  └─┘    └──┘  └┘ └──┘ 
doc       └┘   └─┘       └──┘   └┘  └──┘        └┘   └─┘       └──┘   └┘  └──┘
1576  if h01 : (0 : β) = 1 then by haveI := subsingleton_of_zero_eq_one β h01;
id   └┘                                  └─────────────────────────┘  └─┘
src  └┘                          └───────┘└─────────────────────────┘ 
typ  └┘                         └───────┘└─────────────────────────┘└─┘
doc                               └───────┘└─────────────────────────┘ 
txt                               └───────┘                            
par                               └───────┘                            
pid                                    └─┘                            
st                               └────────────────────────────────────────────
1577    exact ⟨subsingleton.elim _ _, subsingleton.elim _ _⟩
id                                   └───────────────┘
src    └────┘                  └────┘└───────────────┘└────┘
typ    └────┘                  └────┘└───────────────┘└────┘
doc    └────┘                  └────┘                 └────┘
txt    └────┘                  └────┘                 └────┘
par    └────┘                  └────┘                 └────┘
pid                           └────┘                 └───┘
st   ──────────────────────────────────────────────────────┘
1578  else
1579  have h01α : (0 : α) ≠ 1, from mt (congr_arg f)
id   └──┘                        └┘  └───────┘ 
src                               └┘  └───────┘
typ  └──┘                        └┘  └───────┘ 
1580    (by rwa [is_semiring_hom.map_one f, is_semiring_hom.map_zero f]),
id              └─────────────────────┘   └──────────────────────┘ 
src        └───┘└─────────────────────┘ └┘└──────────────────────┘ 
typ        └───┘└─────────────────────┘└┘└──────────────────────┘
doc        └───┘                        └┘                         
txt        └───┘                        └┘                         
par        └───┘                        └┘                         
pid           └┘                        └┘                         
st        └─────────────────────────────┘└──────────────────────────┘
1581  have map f p /ₘ map f q = map f (p /ₘ q) ∧ map f p %ₘ map f q = map f (p %ₘ q),
id        └─┘   └┘ └─┘    └─┘    └┘    └─┘   └┘ └─┘    └─┘    └┘ 
src       └─┘     └┘ └─┘      └─┘      └┘     └─┘     └┘ └─┘      └─┘      └┘
typ       └─┘   └┘ └─┘    └─┘    └┘    └─┘   └┘ └─┘    └─┘    └┘ 
doc       └─┘     └┘ └─┘       └─┘      └┘      └─┘     └┘ └─┘       └─┘      └┘
1582    from (div_mod_by_monic_unique ((p /ₘ q).map f) _ (monic_map f hq)
id           └─────────────────────┘    └┘  └─┘       └───────┘  └┘
src          └─────────────────────┘     └┘   └─┘        └───────┘
typ          └─────────────────────┘    └┘  └─┘       └───────┘  └┘
doc                                      └┘   └─┘
1583      ⟨eq.symm $ by rw [← map_mul, ← map_add, mod_by_monic_add_div _ hq],
id        └─────┘            └─────┘    └─────┘  └──────────────────┘   └┘
src       └─────┘      └────┘└─────┘└──┘└─────┘└┘└──────────────────┘└─┘  
typ       └─────┘      └────┘└─────┘└──┘└─────┘└┘└──────────────────┘└─┘└┘
doc                    └────┘       └──┘       └┘                    └─┘  
txt                    └────┘       └──┘       └┘                    └─┘  
par                    └────┘       └──┘       └┘                    └─┘  
pid                      └──┘       └──┘       └┘                    └─┘  
st                    └────────────┘└─────────┘└─────────────────────────┘
1584      calc _ ≤ degree (p %ₘ q) : degree_map_le _
id                └────┘   └┘     └───────────┘
src               └────┘    └┘      └───────────┘
typ               └────┘   └┘     └───────────┘
doc               └────┘    └┘
1585      ... < degree q : degree_mod_by_monic_lt _ hq
id             └────┘    └────────────────────┘   └┘
src            └────┘     └────────────────────┘
typ            └────┘    └────────────────────┘   └┘
doc            └────┘
1586        $ (ne_zero_of_monic_of_zero_ne_one hq h01α)
id            └─────────────────────────────┘ └┘ └──┘
src           └─────────────────────────────┘
typ           └─────────────────────────────┘ └┘ └──┘
1587      ... = _ : eq.symm $ degree_map_eq_of_leading_coeff_ne_zero _
id                 └─────┘   └────────────────────────────────────┘
src                └─────┘   └────────────────────────────────────┘
typ                └─────┘   └────────────────────────────────────┘
1588        (by rw [monic.def.1 hq, is_semiring_hom.map_one f]; exact ne.symm h01)⟩),
id                 └───────┘   └┘  └─────────────────────┘          └─────┘ └─┘
src            └──┘└───────┘└─┘  └┘└─────────────────────┘   └────┘└─────┘
typ            └──┘└───────┘└─┘└┘└┘└─────────────────────┘  └────┘└─────┘└─┘
doc            └──┘         └─┘  └┘                          └────┘       
txt            └──┘         └─┘  └┘                          └────┘       
par            └──┘         └─┘  └┘                          └────┘       
pid              └┘         └─┘  └┘                                      
st            └─────────────────┘└─────────────────────────┘└─────────────────┘
1589  ⟨this.1.symm, this.2.symm⟩
id    └──┘ └──┘   └──┘ └──┘
src        └──┘        └──┘
typ   └──┘ └──┘   └──┘ └──┘
1590  
1591  lemma map_div_by_monic [comm_ring β] (f : α → β) [is_semiring_hom f] (hq : monic q) :
id                           └───────┘              └─────────────┘         └───┘ 
src                          └───────┘                 └─────────────┘          └───┘
typ                          └───────┘              └─────────────┘         └───┘ 
doc                                                    └─────────────┘          └───┘
1592    (p /ₘ q).map f = p.map f /ₘ q.map f :=
id       └┘  └─┘    └──┘  └┘ └──┘ 
src       └┘   └─┘      └──┘   └┘  └──┘
typ      └┘  └─┘    └──┘  └┘ └──┘ 
doc       └┘   └─┘       └──┘   └┘  └──┘
1593  (map_mod_div_by_monic f hq).1
id    └──────────────────┘  └┘ 
src   └──────────────────┘      
typ   └──────────────────┘  └┘ 
1594  
1595  lemma map_mod_by_monic [comm_ring β] (f : α → β) [is_semiring_hom f] (hq : monic q) :
id                           └───────┘              └─────────────┘         └───┘ 
src                          └───────┘                 └─────────────┘          └───┘
typ                          └───────┘              └─────────────┘         └───┘ 
doc                                                    └─────────────┘          └───┘
1596    (p %ₘ q).map f = p.map f %ₘ q.map f :=
id       └┘  └─┘    └──┘  └┘ └──┘ 
src       └┘   └─┘      └──┘   └┘  └──┘
typ      └┘  └─┘    └──┘  └┘ └──┘ 
doc       └┘   └─┘       └──┘   └┘  └──┘
1597  (map_mod_div_by_monic f hq).2
id    └──────────────────┘  └┘ 
src   └──────────────────┘      
typ   └──────────────────┘  └┘ 
1598  
1599  lemma dvd_iff_mod_by_monic_eq_zero (hq : monic q) : p %ₘ q = 0 ↔ q ∣ p :=
id                                            └───┘      └┘        
src                                           └───┘        └┘         
typ                                           └───┘      └┘        
doc                                           └───┘        └┘
1600  ⟨λ h, by rw [← mod_by_monic_add_div p hq, h, zero_add];
id                 └──────────────────┘  └┘    └──────┘
src           └────┘└──────────────────┘   └┘ └┘└──────┘
typ          └────┘└──────────────────┘└┘└┘└┘└──────┘
doc           └────┘                       └┘ └┘        
txt           └────┘                       └┘ └┘        
par           └────┘                       └┘ └┘        
pid             └──┘                       └┘ └┘        
st           └──────────────────────────────┘└─┘└────────┘└─
1601    exact dvd_mul_right _ _,
id           └───────────┘
src    └────┘└───────────┘└──┘
typ    └────┘└───────────┘└──┘
doc    └────┘             └──┘
txt    └────┘             └──┘
par    └────┘             └──┘
pid                      └──┘
st   ────────────────────────┘
1602  λ h, if hq0 : q = 0 then by rw hq0 at hq;
id       └┘                      └─┘
src       └┘                    └─┘   └────┘
typ      └┘                   └─┘└─┘└────┘
doc                              └─┘   └────┘
txt                              └─┘   └────┘
par                              └─┘   └────┘
pid                                   └────┘
st                              └──────────────
1603    exact (subsingleton_of_monic_zero hq).1 _ _
id            └────────────────────────┘ └┘
src    └────┘ └────────────────────────┘  └───────
typ    └────┘ └────────────────────────┘└┘└───────
doc    └────┘                             └───────
txt    └────┘                             └───────
par    └────┘                             └───────
pid                                      └─────┘
st   ──────────────────────────────────────────────
1604    else
src  ─┘
typ  ─┘
doc  ─┘
txt  ─┘
par  ─┘
pid  ─┘
st   ─┘
1605    let ⟨r, hr⟩ := exists_eq_mul_right_of_dvd h in
id     └─┘           └────────────────────────┘ 
src                   └────────────────────────┘
typ    └─┘           └────────────────────────┘ 
1606    by_contradiction (λ hpq0,
id     └──────────────┘    └──┘
src    └──────────────┘
typ    └──────────────┘    └──┘
1607    have hmod : p %ₘ q = q * (r - p /ₘ q) :=
id                  └┘          └┘ 
src                  └┘             └┘
typ                 └┘          └┘ 
doc                  └┘                └┘
1608      by rw [mod_by_monic_eq_sub_mul_div _ hq, mul_sub, ← hr],
id              └─────────────────────────┘   └┘  └─────┘    └┘
src         └──┘└─────────────────────────┘└─┘  └┘└─────┘└──┘  
typ         └──┘└─────────────────────────┘└─┘└┘└┘└─────┘└──┘└┘
doc         └──┘                           └─┘  └┘       └──┘  
txt         └──┘                           └─┘  └┘       └──┘  
par         └──┘                           └─┘  └┘       └──┘  
pid           └┘                           └─┘  └┘       └──┘  
st         └───────────────────────────────────┘└───────┘└────┘
1609    have degree (q * (r - p /ₘ q)) < degree q :=
id          └────┘         └┘     └────┘ 
src         └────┘           └┘      └────┘
typ         └────┘         └┘     └────┘ 
doc         └────┘             └┘       └────┘
1610      hmod ▸ degree_mod_by_monic_lt _ hq hq0,
id       └──┘  └────────────────────┘   └┘ └─┘
src            └────────────────────┘
typ      └──┘  └────────────────────┘   └┘ └─┘
1611    have hrpq0 : leading_coeff (r - p /ₘ q) ≠ 0 :=
id                  └───────────┘      └┘   
src                 └───────────┘       └┘    
typ                 └───────────┘      └┘   
doc                 └───────────┘        └┘
1612      λ h, hpq0 $ leading_coeff_eq_zero.1
id           └──┘   └───────────────────┘
src                  └───────────────────┘
typ          └──┘   └───────────────────┘
1613        (by rw [hmod, leading_coeff_eq_zero.1 h, mul_zero, leading_coeff_zero]),
id                 └──┘  └───────────────────┘     └──────┘  └────────────────┘
src            └──┘    └┘└───────────────────┘└─┘ └┘└──────┘└┘└────────────────┘
typ            └──┘└──┘└┘└───────────────────┘└─┘└┘└──────┘└┘└────────────────┘
doc            └──┘    └┘                     └─┘ └┘        └┘                  
txt            └──┘    └┘                     └─┘ └┘        └┘                  
par            └──┘    └┘                     └─┘ └┘        └┘                  
pid              └┘    └┘                     └─┘ └┘        └┘                  
st            └───────┘└─────────────────────────┘└────────┘└──────────────────┘
1614    have hlc : leading_coeff q * leading_coeff (r - p /ₘ q) ≠ 0 :=
id                └───────────┘   └───────────┘      └┘   
src               └───────────┘    └───────────┘       └┘    
typ               └───────────┘   └───────────┘      └┘   
doc               └───────────┘     └───────────┘        └┘
1615      by rwa [monic.def.1 hq, one_mul],
id               └───────┘   └┘  └─────┘
src         └───┘└───────┘└─┘  └┘└─────┘
typ         └───┘└───────┘└─┘└┘└┘└─────┘
doc         └───┘         └─┘  └┘       
txt         └───┘         └─┘  └┘       
par         └───┘         └─┘  └┘       
pid            └┘         └─┘  └┘       
st         └──────────────────┘└───────┘
1616    by rw [degree_mul_eq' hlc, degree_eq_nat_degree hq0,
id            └────────────┘ └─┘  └──────────────────┘ └─┘
src       └──┘└────────────┘   └┘└──────────────────┘   └─
typ       └──┘└────────────┘└─┘└┘└──────────────────┘└─┘└─
doc       └──┘                 └┘                       └─
txt       └──┘                 └┘                       └─
par       └──┘                 └┘                       └─
pid         └┘                 └┘                       └─
st       └─────────────────────┘└────────────────────────┘└─
1617        degree_eq_nat_degree (mt leading_coeff_eq_zero.2 hrpq0)] at this;
id         └──────────────────┘  └┘ └───────────────────┘   └───┘
src  ─────┘└──────────────────┘ └┘└───────────────────┘└─┘     └────────┘
typ  ─────┘└──────────────────┘ └┘└───────────────────┘└─┘└───┘└────────┘
doc  ─────┘                                            └─┘     └────────┘
txt  ─────┘                                            └─┘     └────────┘
par  ─────┘                                            └─┘     └────────┘
pid  ─────┘                                            └─┘     └┘└──────┘
st   ────────────────────────────────────────────────────────────┘└─────────
1618      exact not_lt_of_ge (nat.le_add_right _ _) (with_bot.some_lt_some.1 this))⟩
id             └──────────┘  └──────────────┘       └───────────────────┘   └──┘
src      └────┘└──────────┘ └──────────────┘└────┘ └───────────────────┘└─┘    
typ      └────┘└──────────┘ └──────────────┘└────┘ └───────────────────┘└─┘└──┘
doc      └────┘                             └────┘                      └─┘    
txt      └────┘                             └────┘                      └─┘    
par      └────┘                             └────┘                      └─┘    
pid                                        └────┘                      └─┘    
st   ───────────────────────────────────────────────────────────────────────────┘
1619  
1620  @[simp] lemma mod_by_monic_one (p : polynomial α) : p %ₘ 1 = 0 :=
id                                       └────────┘      └┘   
src                                      └────────┘        └┘   
typ                                      └────────┘      └┘   
doc    └──┘                              └────────┘        └┘
1621  (dvd_iff_mod_by_monic_eq_zero monic_one).2 (one_dvd _)
id    └──────────────────────────┘ └───────┘    └─────┘
src   └──────────────────────────┘ └───────┘    └─────┘
typ   └──────────────────────────┘ └───────┘    └─────┘
1622  
1623  @[simp] lemma div_by_monic_one (p : polynomial α) : p /ₘ 1 = p :=
id                                       └────────┘      └┘    
src                                      └────────┘        └┘   
typ                                      └────────┘      └┘    
doc    └──┘                              └────────┘        └┘
1624  by conv_rhs { rw [← mod_by_monic_add_div p monic_one] }; simp
id                       └──────────────────┘  └───────┘
src     └─────────┘└────┘└──────────────────┘ └───────┘└┘  └────
typ     └─────────┘└────┘└──────────────────┘└───────┘└┘  └────
doc                                                           └────
txt     └─────────┘└────┘                              └┘  └────
par     └─────────┘└────┘                              └┘  └────
pid             └──────┘                              └─┘      
st     └─────────┘└─────────────────────────────────────┘ └┘└─────
1625  
src  
typ  
doc  
txt  
par  
pid  
st   
1626  lemma degree_pos_of_root (hp : p ≠ 0) (h : is_root p a) : 0 < degree p :=
id                                            └─────┘         └────┘ 
src                                            └─────┘           └────┘
typ                                           └─────┘         └────┘ 
doc                                             └─────┘            └────┘
1627  lt_of_not_ge $ λ hlt, begin
id   └──────────┘     └─┘
src  └──────────┘
typ  └──────────┘     └─┘
st                         └─────
1628    have := eq_C_of_degree_le_zero hlt,
id             └────────────────────┘ └─┘
src    └──────┘└────────────────────┘
typ    └──────┘└────────────────────┘└─┘
doc    └──────┘                      
txt    └──────┘                      
par    └──────┘                      
pid    └───┘└─┘                      
st   ───────────────────────────────────┘└─
1629    rw [is_root, this, eval_C] at h,
id         └─────┘  └──┘  └────┘
src    └──┘└─────┘└┘    └┘└────┘└────┘
typ    └──┘└─────┘└┘└──┘└┘└────┘└────┘
doc    └──┘└─────┘└┘    └┘      └────┘
txt    └──┘       └┘    └┘      └────┘
par    └──┘       └┘    └┘      └────┘
pid      └┘       └┘    └┘      └───┘
st   ────────────┘└────┘└──────┘└───┘└─
1630    exact hp (finsupp.ext (λ n, show coeff p n = 0, from
id           └┘  └─────────┘            └───┘    
src    └────┘   └─────────┘  └──┘    └───┘  └────────
typ    └────┘└┘ └─────────┘  └──┘    └───┘ └────────
doc    └────┘                └──┘    └───┘   └────────
txt    └────┘                └──┘            └────────
par    └────┘                └──┘            └────────
pid                         └──┘            └────────
st   ───────────────────────────────────────────────────────
1631      nat.cases_on n h (λ _, coeff_eq_zero_of_degree_lt (lt_of_le_of_lt hlt
id       └──────────┘          └────────────────────────┘  └────────────┘ └─┘
src  ───┘└──────────┘    └──┘└────────────────────────┘ └────────────┘   
typ  ───┘└──────────┘   └──┘└────────────────────────┘ └────────────┘└─┘
doc  ───┘                └──┘                                            
txt  ───┘                └──┘                                            
par  ───┘                └──┘                                            
pid  ───┘                └──┘                                            
st   ──────────────────────────────────────────────────────────────────────────
1632        (with_bot.coe_lt_coe.2 (nat.succ_pos _)))))),
id          └─────────────────┘    └──────────┘
src  ─────┘ └─────────────────┘└─┘ └──────────┘└──────┘
typ  ─────┘ └─────────────────┘└─┘ └──────────┘└──────┘
doc  ─────┘                    └─┘             └──────┘
txt  ─────┘                    └─┘             └──────┘
par  ─────┘                    └─┘             └──────┘
pid  ─────┘                    └─┘             └──────┘
st   ─────────────────────────────────────────────────┘└─
1633  end
st   ──┘
1634  
1635  theorem monic_X_sub_C (x : α) : monic (X - C x) :=
id                                  └───┘     
src                                  └───┘    
typ                                 └───┘     
doc                                  └───┘     
1636  by simpa only [C_neg] using monic_X_add_C (-x)
id                  └───┘        └───────────┘  
src     └──────────┘└───┘└──────┘└───────────┘  └─
typ     └──────────┘└───┘└──────┘└───────────┘ └─
doc     └──────────┘     └──────┘                └─
txt     └──────────┘     └──────┘                └─
par     └──────────┘     └──────┘                └─
pid          └──┘└┘     └────┘                
st     └────────────────────────────────────────────
1637  
src  
typ  
doc  
txt  
par  
pid  
st   
1638  theorem monic_X_pow_sub {n : ℕ} (H : degree p ≤ n) : monic (X ^ (n+1) - p) :=
id                                       └────┘       └───┘         
src                                      └────┘         └───┘         
typ                                      └────┘       └───┘         
doc                                       └────┘          └───┘  
1639  monic_X_pow_add ((degree_neg p).symm ▸ H)
id   └─────────────┘   └────────┘  └──┘   
src  └─────────────┘   └────────┘   └──┘  
typ  └─────────────┘   └────────┘  └──┘   
1640  
1641  theorem degree_mod_by_monic_le (p : polynomial α) {q : polynomial α}
id                                       └────────┘        └────────┘ 
src                                      └────────┘         └────────┘
typ                                      └────────┘        └────────┘ 
doc                                      └────────┘         └────────┘
1642    (hq : monic q) : degree (p %ₘ q) ≤ degree q :=
id           └───┘     └────┘   └┘    └────┘ 
src          └───┘      └────┘    └┘     └────┘
typ          └───┘     └────┘   └┘    └────┘ 
doc          └───┘      └────┘    └┘      └────┘
1643  decidable.by_cases
id   └────────────────┘
src  └────────────────┘
typ  └────────────────┘
1644    (assume H : q = 0, by rw [monic, H, leading_coeff_zero] at hq;
id                             └───┘    └────────────────┘
src                         └──┘└───┘└┘ └┘└────────────────┘└─────┘
typ                        └──┘└───┘└┘└┘└────────────────┘└─────┘
doc                          └──┘└───┘└┘ └┘                  └─────┘
txt                          └──┘     └┘ └┘                  └─────┘
par                          └──┘     └┘ └┘                  └─────┘
pid                            └┘     └┘ └┘                  └────┘
st                          └────────┘└─┘└──────────────────┘└───────
1645      have : (0:polynomial α) = 1 := (by rw [← C_0, ← C_1, hq]);
id                 └────────┘                   └─┘    └─┘  └┘
src      └─────┘ └┘└────────┘ └┘└────┘   └────┘└─┘└──┘└─┘└┘
typ      └─────┘ └┘└────────┘└┘└────┘   └────┘└─┘└──┘└─┘└┘└┘
doc      └─────┘ └┘└────────┘ └┘ └────┘   └────┘   └──┘   └┘
txt      └─────┘ └┘           └┘ └────┘   └────┘   └──┘   └┘
par      └─────┘ └┘           └┘ └────┘   └────┘   └──┘   └┘
pid      └───┘└┘ └┘           └┘ └───┘   └─────┘   └──┘   └┘
st   ─────────────────────────────────────┘└────────┘└─────┘└──┘
1646      rw [eq_zero_of_zero_eq_one _ this (p %ₘ q), eq_zero_of_zero_eq_one _ this q]; exact le_refl _)
id       └┘
src      └┘
typ      └┘
doc      └┘
1647    (assume H : q ≠ 0, le_of_lt $ degree_mod_by_monic_lt _ hq H)
1648  
1649  lemma root_X_sub_C : is_root (X - C a) b ↔ a = b :=
id                                              
src                                           
typ                                             
1650  by rw [is_root.def, eval_sub, eval_X, eval_C, sub_eq_zero_iff_eq, eq_comm]
st                                                                            
1651  
1652  def nonzero_comm_ring.of_polynomial_ne (h : p ≠ q) : nonzero_comm_ring α :=
id                                                         └┘  └┘  └┘  └┘   
src                                                        └┘  └┘  └┘  └┘
typ                                                        └┘  └┘  └┘  └┘   
doc                                                        └┘  └┘  └┘  └┘
1653  { zero := 0,
1654    one := 1,
1655    zero_ne_one := λ h01, h $
1656      by rw [← one_mul p, ← one_mul q, ← C_1, ← h01, C_0, zero_mul, zero_mul],
st                                                                             
1657    ..show comm_ring α, by apply_instance }
id                      
typ                     
1658  
1659  end comm_ring
1660  
1661  section nonzero_comm_ring
1662  variables [nonzero_comm_ring α] {p q : polynomial α}
id              └┘  └──┘  └──┘  
src             └┘  └──┘  └──┘  
typ             └┘  └──┘  └──┘  
doc             └┘  └──┘  └──┘  
1663  
1664  instance : nonzero_comm_ring (polynomial α) :=
id              └┘  └┘  └┘  └┘               
src             └┘  └┘  └┘  └┘  
typ             └┘  └┘  └┘  └┘               
doc             └┘  └┘  └┘  └┘  
1665  { ..polynomial.nonzero_comm_semiring,
1666    ..polynomial.comm_ring }
1667  
1668  @[simp] lemma degree_X_sub_C (a : α) : degree (X - C a) = 1 :=
id                                                       
typ                                                      
doc    └──┘
1669  begin
1670    rw [sub_eq_add_neg, add_comm, ← @degree_X α],
id                                               
typ                                              
1671    by_cases ha : a = 0,
id                   
typ                  
1672    { simp only [ha, C_0, neg_zero, zero_add] },
st                                               └┘
1673    exact degree_add_eq_of_degree_lt (by rw [degree_X, degree_neg, degree_C ha]; exact dec_trivial)
1674  end
st   └─┘
1675  
1676  lemma degree_X_pow_sub_C {n : ℕ} (hn : 0 < n) (a : α) :
id                                                    
src                                
typ                                                   
1677    degree ((X : polynomial α) ^ n - C a) = n :=
id                                          
typ                                         
1678  have degree (-C a) < degree ((X : polynomial α) ^ n),
id                                                   
typ                                                  
1679    from calc degree (-C a) ≤ 0 : by rw degree_neg; exact degree_C_le
id                          
typ                         
1680    ... < degree ((X : polynomial α) ^ n) : by rwa [degree_X_pow];
id                                       
typ                                      
1681      exact with_bot.coe_lt_coe.2 hn,
1682  by rw [sub_eq_add_neg, add_comm, degree_add_eq_of_degree_lt this, degree_X_pow]
st                                                                                 
1683  
1684  lemma X_pow_sub_C_ne_zero {n : ℕ} (hn : 0 < n) (a : α) :
id                                                     
src                                 
typ                                                    
1685    (X : polynomial α) ^ n - C a ≠ 0 :=
id                              
typ                             
1686  mt degree_eq_bot.2 (show degree ((X : polynomial α) ^ n - C a) ≠ ⊥,
id                                                             
typ                                                            
1687    by rw degree_X_pow_sub_C hn; exact dec_trivial)
1688  
1689  end nonzero_comm_ring
1690  
1691  section comm_ring
1692  
1693  variables [comm_ring α] {p q : polynomial α}
id              └┘  └──┘
src             └┘  └──┘
typ             └┘  └──┘
1694  
1695  @[simp] lemma mod_by_monic_X_sub_C_eq_C_eval (p : polynomial α) (a : α) : p %ₘ (X - C a) = C (p.eval a) :=
id                                                                                                     
typ                                                                                                    
doc    └──┘
1696  if h0 : (0 : α) = 1 then by letI := subsingleton_of_zero_eq_one α h0; exact subsingleton.elim _ _
id                                                                  
typ                                                                 
1697  else
1698  by letI : nonzero_comm_ring α := nonzero_comm_ring.of_ne h0; exact
id             └───────────────┘ 
src            └───────────────┘
typ            └───────────────┘ 
doc            └───────────────┘
1699  have h : (p %ₘ (X - C a)).eval a = p.eval a :=
1700    by rw [mod_by_monic_eq_sub_mul_div _ (monic_X_sub_C a), eval_sub, eval_mul,
id                                                         
typ                                                        
1701      eval_sub, eval_X, eval_C, sub_self, zero_mul, sub_zero],
st                                                             
1702  have degree (p %ₘ (X - C a)) < 1 :=
1703    degree_X_sub_C a ▸ degree_mod_by_monic_lt p (monic_X_sub_C a) ((degree_X_sub_C a).symm ▸
id                                                                                    
typ                                                                                   
1704      ne_zero_of_monic (monic_X_sub_C _)),
1705  have degree (p %ₘ (X - C a)) ≤ 0 :=
1706    begin
1707      cases (degree (p %ₘ (X - C a))),
id                                  
typ                                 
1708      { exact bot_le },
st                      └┘
1709      { exact with_bot.some_le_some.2 (nat.le_of_lt_succ (with_bot.some_lt_some.1 this)) }
st                                                                                          └┘
1710    end,
st     └─┘
1711  begin
1712    rw [eq_C_of_degree_le_zero this, eval_C] at h,
1713    rw [eq_C_of_degree_le_zero this, h]
st                                       
1714  end
st   └─┘
1715  
1716  lemma mul_div_by_monic_eq_iff_is_root : (X - C a) * (p /ₘ (X - C a)) = p ↔ is_root p a :=
id                                                                                     
src                                                                           
typ                                                                                    
1717  ⟨λ h, by rw [← h, is_root.def, eval_mul, eval_sub, eval_X, eval_C, sub_self, zero_mul],
st                                                                                        
1718  λ h : p.eval a = 0,
id                
typ               
1719    by conv {to_rhs, rw ← mod_by_monic_add_div p (monic_X_sub_C a)};
id                                                                 
typ                                                                
1720      rw [mod_by_monic_X_sub_C_eq_C_eval, h, C_0, zero_add]⟩
st                                                           
1721  
1722  lemma dvd_iff_is_root : (X - C a) ∣ p ↔ is_root p a :=
id                                                   
src                                        
typ                                                  
1723  ⟨λ h, by rwa [← dvd_iff_mod_by_monic_eq_zero (monic_X_sub_C _),
1724      mod_by_monic_X_sub_C_eq_C_eval, ← C_0, C_inj] at h,
1725    λ h, ⟨(p /ₘ (X - C a)), by rw mul_div_by_monic_eq_iff_is_root.2 h⟩⟩
id                        
typ                       
1726  
1727  lemma mod_by_monic_X (p : polynomial α) : p %ₘ X = C (p.eval 0) :=
id                                        
typ                                       
1728  by rw [← mod_by_monic_X_sub_C_eq_C_eval, C_0, sub_zero]
st                                                         
1729  
1730  section multiplicity
1731  
1732  def decidable_dvd_monic (p : polynomial α) (hq : monic q) : decidable (q ∣ p) :=
id                                                              └┘  └┘  
src                                                              └┘  └┘  
typ                                                             └┘  └┘  
1733  decidable_of_iff (p %ₘ q = 0) (dvd_iff_mod_by_monic_eq_zero hq)
1734  
1735  open_locale classical
1736  
1737  lemma multiplicity_X_sub_C_finite (a : α) (h0 : p ≠ 0) :
id                                          
typ                                         
1738    multiplicity.finite (X - C a) p :=
id                                
typ                               
1739  multiplicity_finite_of_degree_pos_of_monic
1740    (have (0 : α) ≠ 1, from (λ h, by haveI := subsingleton_of_zero_eq_one _ h;
id                
typ               
1741        exact h0 (subsingleton.elim _ _)),
1742      by letI : nonzero_comm_ring α := { zero_ne_one := this, ..show comm_ring α, by apply_instance };
id                 └───────────────┘                                   └───────┘ 
src                └───────────────┘                                    └───────┘
typ                └───────────────┘                                   └───────┘ 
doc                └───────────────┘
1743        rw degree_X_sub_C; exact dec_trivial)
1744      (monic_X_sub_C _) h0
1745  
1746  def root_multiplicity (a : α) (p : polynomial α) : ℕ :=
id                                                    
src                                                     
typ                                                   
1747  if h0 : p = 0 then 0
1748  else let I : decidable_pred (λ n : ℕ, ¬(X - C a) ^ (n + 1) ∣ p) :=
id                                                    
src                                       
typ                                                   
1749    λ n, @not.decidable _ (decidable_dvd_monic p (monic_pow (monic_X_sub_C a) (n + 1))) in
id                                                                              
typ                                                                             
1750  by exactI nat.find (multiplicity_X_sub_C_finite a h0)
1751  
1752  lemma root_multiplicity_eq_multiplicity (p : polynomial α) (a : α) :
id                                                                  
typ                                                                 
1753    root_multiplicity a p = if h0 : p = 0 then 0 else
id                       
typ                      
1754    (multiplicity (X - C a) p).get (multiplicity_X_sub_C_finite a h0) :=
id                                                                
typ                                                               
1755  by simp [multiplicity, root_multiplicity, roption.dom];
1756    congr; funext; congr
id     └───┘          └───┘
src    └───┘          └───┘
typ    └───┘          └───┘
1757  
1758  lemma pow_root_multiplicity_dvd (p : polynomial α) (a : α) :
id                                                          
typ                                                         
1759    (X - C a) ^ root_multiplicity a p ∣ p :=
id                                  
typ                                 
1760  if h : p = 0 then by simp [h]
1761  else by rw [root_multiplicity_eq_multiplicity, dif_neg h];
1762    exact multiplicity.pow_multiplicity_dvd _
1763  
1764  lemma div_by_monic_mul_pow_root_multiplicity_eq
1765    (p : polynomial α) (a : α) :
id                            
typ                           
1766    p /ₘ ((X - C a) ^ root_multiplicity a p) *
id                                        
typ                                       
1767    (X - C a) ^ root_multiplicity a p = p :=
id                                  
typ                                 
1768  have monic ((X - C a) ^ root_multiplicity a p),
id                                            
typ                                           
1769    from monic_pow (monic_X_sub_C _) _,
1770  by conv_rhs { rw [← mod_by_monic_add_div p this,
1771      (dvd_iff_mod_by_monic_eq_zero this).2 (pow_root_multiplicity_dvd _ _)] };
1772    simp [mul_comm]
1773  
1774  lemma eval_div_by_monic_pow_root_multiplicity_ne_zero
1775    {p : polynomial α} (a : α) (hp : p ≠ 0) :
id                            
typ                           
1776    (p /ₘ ((X - C a) ^ root_multiplicity a p)).eval a ≠ 0 :=
id                                                   
typ                                                  
1777  begin
1778    letI : nonzero_comm_ring α := nonzero_comm_ring.of_polynomial_ne hp,
id            └───────────────┘ 
src           └───────────────┘
typ           └───────────────┘ 
doc           └───────────────┘
1779    rw [ne.def, ← is_root.def, ← dvd_iff_is_root],
1780    rintros ⟨q, hq⟩,
1781    have := div_by_monic_mul_pow_root_multiplicity_eq p a,
id                                                         
typ                                                        
1782    rw [mul_comm, hq, ← mul_assoc, ← pow_succ',
1783      root_multiplicity_eq_multiplicity, dif_neg hp] at this,
1784    exact multiplicity.is_greatest'
1785      (multiplicity_finite_of_degree_pos_of_monic
1786      (show (0 : with_bot ℕ) < degree (X - C a),
id                  └──────┘                    
src                 └──────┘
typ                 └──────┘                    
1787        by rw degree_X_sub_C; exact dec_trivial) _ hp)
1788      (nat.lt_succ_self _) (dvd_of_mul_right_eq _ this)
1789  end
st   └─┘
1790  
1791  end multiplicity
1792  
1793  end comm_ring
1794  
1795  section integral_domain
1796  variables [integral_domain α] {p q : polynomial α}
id              └┘  └──┘  └──┘
src             └┘  └──┘  └──┘
typ             └┘  └──┘  └──┘
1797  
1798  @[simp] lemma degree_mul_eq : degree (p * q) = degree p + degree q :=
doc    └──┘
1799  if hp0 : p = 0 then by simp only [hp0, degree_zero, zero_mul, with_bot.bot_add]
1800  else if hq0 : q = 0 then  by simp only [hq0, degree_zero, mul_zero, with_bot.add_bot]
1801  else degree_mul_eq' $ mul_ne_zero (mt leading_coeff_eq_zero.1 hp0)
1802      (mt leading_coeff_eq_zero.1 hq0)
1803  
1804  @[simp] lemma degree_pow_eq (p : polynomial α) (n : ℕ) :
id                                                      
src                                                      
typ                                                     
doc    └──┘
1805    degree (p ^ n) = add_monoid.smul n (degree p) :=
id                                     
typ                                    
1806  by induction n; [simp only [pow_zero, degree_one, add_monoid.zero_smul],
1807  simp only [*, pow_succ, succ_smul, degree_mul_eq]]
1808  
1809  @[simp] lemma leading_coeff_mul (p q : polynomial α) : leading_coeff (p * q) =
id                                                     
typ                                                    
doc    └──┘
1810    leading_coeff p * leading_coeff q :=
1811  begin
1812    by_cases hp : p = 0,
1813    { simp only [hp, zero_mul, leading_coeff_zero] },
st                                                    └┘
1814    { by_cases hq : q = 0,
1815      { simp only [hq, mul_zero, leading_coeff_zero] },
st                                                      └┘
1816      { rw [leading_coeff_mul'],
1817        exact mul_ne_zero (mt leading_coeff_eq_zero.1 hp) (mt leading_coeff_eq_zero.1 hq) } }
st                                                                                           └───
1818  end
st   ──┘
1819  
1820  @[simp] lemma leading_coeff_pow (p : polynomial α) (n : ℕ) :
id                                                          
src                                                          
typ                                                         
doc    └──┘
1821    leading_coeff (p ^ n) = leading_coeff p ^ n :=
id                                              
typ                                             
1822  by induction n; [simp only [pow_zero, leading_coeff_one],
1823  simp only [*, pow_succ, leading_coeff_mul]]
1824  
1825  instance : integral_domain (polynomial α) :=
id              └┘  └┘  └┘  └┘              
src             └┘  └┘  └┘  └┘
typ             └┘  └┘  └┘  └┘              
1826  { eq_zero_or_eq_zero_of_mul_eq_zero := λ a b h, begin
1827      have : leading_coeff 0 = leading_coeff a * leading_coeff b := h ▸ leading_coeff_mul a b,
1828      rw [leading_coeff_zero, eq_comm] at this,
1829      erw [← leading_coeff_eq_zero, ← leading_coeff_eq_zero],
1830      exact eq_zero_or_eq_zero_of_mul_eq_zero this
1831    end,
st     └─┘
1832    ..polynomial.nonzero_comm_ring }
1833  
1834  lemma nat_degree_mul_eq (hp : p ≠ 0) (hq : q ≠ 0) : nat_degree (p * q) =
1835    nat_degree p + nat_degree q :=
1836  by rw [← with_bot.coe_eq_coe, ← degree_eq_nat_degree (mul_ne_zero hp hq),
1837      with_bot.coe_add, ← degree_eq_nat_degree hp,
1838      ← degree_eq_nat_degree hq, degree_mul_eq]
st                                               
1839  
1840  @[simp] lemma nat_degree_pow_eq (p : polynomial α) (n : ℕ) :
id                                                          
src                                                          
typ                                                         
doc    └──┘
1841    nat_degree (p ^ n) = n * nat_degree p :=
id                         
typ                        
1842  if hp0 : p = 0
1843  then if hn0 : n = 0 then by simp [hp0, hn0]
id                 
typ                
1844    else by rw [hp0, zero_pow (nat.pos_of_ne_zero hn0)]; simp
1845  else nat_degree_pow_eq'
1846    (by rw [← leading_coeff_pow, ne.def, leading_coeff_eq_zero]; exact pow_ne_zero _ hp0)
1847  
1848  lemma root_or_root_of_root_mul (h : is_root (p * q) a) : is_root p a ∨ is_root q a :=
id                                                                                 
src                                                                       
typ                                                                                
1849  by rw [is_root, eval_mul] at h;
1850    exact eq_zero_or_eq_zero_of_mul_eq_zero h
1851  
1852  lemma degree_le_mul_left (p : polynomial α) (hq : q ≠ 0) : degree p ≤ degree (p * q) :=
id                                            
typ                                           
1853  if hp : p = 0 then by simp only [hp, zero_mul, le_refl]
1854  else by rw [degree_mul_eq, degree_eq_nat_degree hp,
1855      degree_eq_nat_degree hq];
1856    exact with_bot.coe_le_coe.2 (nat.le_add_right _ _)
1857  
1858  lemma exists_finset_roots : ∀ {p : polynomial α} (hp : p ≠ 0),
1859    ∃ s : finset α, (s.card : with_bot ℕ) ≤ degree p ∧ ∀ x, x ∈ s ↔ is_root p x
id                                └────┘                                    
src                                └────┘ 
typ                               └────┘                                    
1860  | p := λ hp, by haveI := classical.prop_decidable (∃ x, is_root p x); exact
id                            └──────────────────────┘    
src                           └──────────────────────┘
typ                           └──────────────────────┘    
1861  if h : ∃ x, is_root p x
id            
typ           
1862  then
1863    let ⟨x, hx⟩ := h in
id          
typ         
1864    have hpd : 0 < degree p := degree_pos_of_root hp hx,
1865    have hd0 : p /ₘ (X - C x) ≠ 0 :=
1866      λ h, by rw [← mul_div_by_monic_eq_iff_is_root.2 hx, h, mul_zero] at hp; exact hp rfl,
1867    have wf : degree (p /ₘ _) < degree p :=
1868      degree_div_by_monic_lt _ (monic_X_sub_C x) hp
1869      ((degree_X_sub_C x).symm ▸ dec_trivial),
1870    let ⟨t, htd, htr⟩ := @exists_finset_roots (p /ₘ (X - C x)) hd0 in
id          
typ         
1871    have hdeg : degree (X - C x) ≤ degree p := begin
1872      rw [degree_X_sub_C, degree_eq_nat_degree hp],
1873      rw degree_eq_nat_degree hp at hpd,
1874      exact with_bot.coe_le_coe.2 (with_bot.coe_lt_coe.1 hpd)
1875    end,
st     └─┘
1876    have hdiv0 : p /ₘ (X - C x) ≠ 0 := mt (div_by_monic_eq_zero_iff (monic_X_sub_C x)
1877      (ne_zero_of_monic (monic_X_sub_C x))).1 $ not_lt.2 hdeg,
1878    ⟨insert x t, calc (card (insert x t) : with_bot ℕ) ≤ card t + 1 :
id                                            └──────┘
src                                           └──────┘
typ                                           └──────┘
1879      with_bot.coe_le_coe.2 $ finset.card_insert_le _ _
1880      ... ≤ degree p :
1881        by rw [← degree_add_div_by_monic (monic_X_sub_C x) hdeg,
id                                                         
typ                                                        
1882            degree_X_sub_C, add_comm];
1883          exact add_le_add' (le_refl (1 : with_bot ℕ)) htd,
id                                           └──────┘
src                                          └──────┘
typ                                          └──────┘
1884    begin
1885      assume y,
1886      rw [mem_insert, htr, eq_comm, ← root_X_sub_C],
1887      conv {to_rhs, rw ← mul_div_by_monic_eq_iff_is_root.2 hx},
1888      exact ⟨λ h, or.cases_on h (root_mul_right_of_is_root _) (root_mul_left_of_is_root _),
1889        root_or_root_of_root_mul⟩
1890    end⟩
st     └─┘
1891  else
1892    ⟨∅, (degree_eq_nat_degree hp).symm ▸ with_bot.coe_le_coe.2 (nat.zero_le _),
1893      by simpa only [not_mem_empty, false_iff, not_exists] using h⟩
1894  using_well_founded {dec_tac := tactic.assumption}
id                                  └───────────────┘
src                                 └───────────────┘
typ                                 └───────────────┘
1895  
1896  /-- `roots p` noncomputably gives a finset containing all the roots of `p` -/
1897  noncomputable def roots (p : polynomial α) : finset α :=
id                                               └┘  └┘ 
src                                               └┘  └┘
typ                                              └┘  └┘ 
doc                                               └┘  └┘
1898  if h : p = 0 then ∅ else classical.some (exists_finset_roots h)
1899  
1900  lemma card_roots (hp0 : p ≠ 0) : ((roots p).card : with_bot ℕ) ≤ degree p :=
id                                                      └┘  └┘   
src                                                     └┘  └┘   
typ                                                     └┘  └┘   
1901  begin
1902    unfold roots,
1903    rw dif_neg hp0,
1904    exact (classical.some_spec (exists_finset_roots hp0)).1
1905  end
st   └─┘
1906  
1907  lemma card_roots' {p : polynomial α} (hp0 : p ≠ 0) : p.roots.card ≤ nat_degree p :=
id                                     
typ                                    
1908  with_bot.coe_le_coe.1 (le_trans (card_roots hp0) (le_of_eq $ degree_eq_nat_degree hp0))
1909  
1910  lemma card_roots_sub_C {p : polynomial α} {a : α} (hp0 : 0 < degree p) :
id                                                 
typ                                                
1911    ((p - C a).roots.card : with_bot ℕ) ≤ degree p :=
id                            └┘  └┘   
src                            └┘  └┘   
typ                           └┘  └┘   
1912  calc ((p - C a).roots.card : with_bot ℕ) ≤ degree (p - C a) :
id                               └┘  └┘                     
src                               └┘  └┘   
typ                              └┘  └┘                     
1913    card_roots $ mt sub_eq_zero.1 $ λ h, not_le_of_gt hp0 $ h.symm ▸ degree_C_le
1914  ... = degree p : by rw [sub_eq_add_neg, ← C_neg]; exact degree_add_C hp0
1915  
1916  lemma card_roots_sub_C' {p : polynomial α} {a : α} (hp0 : 0 < degree p) :
id                                                  
typ                                                 
1917    (p - C a).roots.card ≤ nat_degree p :=
id            
typ           
1918  with_bot.coe_le_coe.1 (le_trans (card_roots_sub_C hp0) (le_of_eq $ degree_eq_nat_degree
1919    (λ h, by simp [*, lt_irrefl] at *)))
1920  
1921  @[simp] lemma mem_roots (hp : p ≠ 0) : a ∈ p.roots ↔ is_root p a :=
id                                                                
src                                                     
typ                                                               
doc    └──┘
1922  by unfold roots; rw dif_neg hp; exact (classical.some_spec (exists_finset_roots hp)).2 _
1923  
1924  @[simp] lemma mem_roots_sub_C {p : polynomial α} {a x : α} (hp0 : 0 < degree p) :
id                                                          
typ                                                         
doc    └──┘
1925    x ∈ (p - C a).roots ↔ p.eval x = a :=
id                                  
src                        
typ                                 
1926  (mem_roots (show p - C a ≠ 0, from mt sub_eq_zero.1 $ λ h,
id                          
typ                         
1927      not_le_of_gt hp0 $ h.symm ▸ degree_C_le)).trans
1928    (by rw [is_root.def, eval_sub, eval_C, sub_eq_zero])
st                                                       
1929  
1930  lemma card_roots_X_pow_sub_C {n : ℕ} (hn : 0 < n) (a : α) :
id                                                        
src                                    
typ                                                       
1931    (roots ((X : polynomial α) ^ n - C a)).card ≤ n :=
id                                                
typ                                               
1932  with_bot.coe_le_coe.1 $
1933  calc ((roots ((X : polynomial α) ^ n - C a)).card : with_bot ℕ)
id                                                    └──┘  └┘ 
src                                                      └──┘  └┘ 
typ                                                   └──┘  └┘ 
1934        ≤ degree ((X : polynomial α) ^ n - C a) : card_roots (X_pow_sub_C_ne_zero hn a)
id                                                                                   
typ                                                                                  
1935    ... = n : degree_X_pow_sub_C hn a
id                                    
typ                                   
1936  
1937  /-- `nth_roots n a` noncomputably returns the solutions to `x ^ n = a`-/
1938  def nth_roots {α : Type*} [integral_domain α] (n : ℕ) (a : α) : finset α :=
id                              └┘  └──┘  └──┘                      └┘  
src                             └┘  └──┘  └──┘                        └┘
typ                             └┘  └──┘  └──┘                      └┘  
doc                                                                    └┘
1939  roots ((X : polynomial α) ^ n - C a)
id                                   
typ                                  
1940  
1941  @[simp] lemma mem_nth_roots {α : Type*} [integral_domain α] {n : ℕ} (hn : 0 < n) {a x : α} :
id                                              └──┘  └──┘                               
src                                             └──┘  └──┘           
typ                                             └──┘  └──┘                               
doc    └──┘
1942    x ∈ nth_roots n a ↔ x ^ n = a :=
id                           
src                      
typ                          
1943  by rw [nth_roots, mem_roots (X_pow_sub_C_ne_zero hn a),
1944    is_root.def, eval_sub, eval_C, eval_pow, eval_X, sub_eq_zero_iff_eq]
st                                                                        
1945  
1946  lemma card_nth_roots {α : Type*} [integral_domain α] (n : ℕ) (a : α) :
id                                     └──────┘  └──┘                
src                                    └──────┘  └──┘          
typ                                    └──────┘  └──┘                
1947    (nth_roots n a).card ≤ n :=
id                          
typ                         
1948  if hn : n = 0
id           
typ          
1949  then if h : (X : polynomial α) ^ n - C a = 0
id                                        
typ                                       
1950    then by simp only [nat.zero_le, nth_roots, roots, h, dif_pos rfl, card_empty]
1951    else with_bot.coe_le_coe.1 (le_trans (card_roots h)
1952     (by rw [hn, pow_zero, ← C_1, ← @is_ring_hom.map_sub _ _ _ _ (@C α _)];
id                                                                      
typ                                                                     
1953        exact degree_C_le))
1954  else by rw [← with_bot.coe_le_coe, ← degree_X_pow_sub_C (nat.pos_of_ne_zero hn) a];
id                                                                                   
typ                                                                                  
1955    exact card_roots (X_pow_sub_C_ne_zero (nat.pos_of_ne_zero hn) a)
id                                                                   
typ                                                                  
1956  
1957  lemma coeff_comp_degree_mul_degree (hqd0 : nat_degree q ≠ 0) :
1958    coeff (p.comp q) (nat_degree p * nat_degree q) =
1959    leading_coeff p * leading_coeff q ^ nat_degree p :=
1960  if hp0 : p = 0 then by simp [hp0] else
1961  calc coeff (p.comp q) (nat_degree p * nat_degree q)
1962    = p.sum (λ n a, coeff (C a * q ^ n) (nat_degree p * nat_degree q)) :
id                                   
typ                                  
1963      by rw [comp, eval₂, coeff_sum]
st                                    
1964  ... = coeff (C (leading_coeff p) * q ^ nat_degree p) (nat_degree p * nat_degree q) :
1965    finset.sum_eq_single _
1966    begin
1967      assume b hbs hbp,
1968      have hq0 : q ≠ 0, from λ hq0, hqd0 (by rw [hq0, nat_degree_zero]),
st                                                                      
1969      have : coeff p b ≠ 0, rwa [← apply_eq_coeff, ← finsupp.mem_support_iff],
id                      
typ                     
1970      dsimp [apply_eq_coeff],
1971      refine coeff_eq_zero_of_degree_lt _,
1972      rw [degree_mul_eq, degree_C this, degree_pow_eq, zero_add, degree_eq_nat_degree hq0,
1973        ← with_bot.coe_smul, add_monoid.smul_eq_mul, with_bot.coe_lt_coe, nat.cast_id],
1974      exact (mul_lt_mul_right (nat.pos_of_ne_zero hqd0)).2
1975        (lt_of_le_of_ne (with_bot.coe_le_coe.1 (by rw ← degree_eq_nat_degree hp0; exact le_sup hbs)) hbp)
1976    end
st     └─┘
1977    (by rw [finsupp.mem_support_iff, apply_eq_coeff, ← leading_coeff, ne.def, leading_coeff_eq_zero,
1978        classical.not_not]; simp {contextual := tt})
id                                                 └┘
src                                                └┘
typ                                                └┘
1979  ... = _ :
1980    have coeff (q ^ nat_degree p) (nat_degree p * nat_degree q) = leading_coeff (q ^ nat_degree p),
1981      by rw [leading_coeff, nat_degree_pow_eq],
st                                              
1982    by rw [coeff_C_mul, this, leading_coeff_pow]
st                                                
1983  
1984  lemma nat_degree_comp : nat_degree (p.comp q) = nat_degree p * nat_degree q :=
1985  le_antisymm nat_degree_comp_le
1986    (if hp0 : p = 0 then by rw [hp0, zero_comp, nat_degree_zero, zero_mul]
st                                                                          
1987    else if hqd0 : nat_degree q = 0
1988    then have degree q ≤ 0, by rw [← with_bot.coe_zero, ← hqd0]; exact degree_le_nat_degree,
1989      by rw [eq_C_of_degree_le_zero this]; simp
1990    else le_nat_degree_of_ne_zero $
1991      have hq0 : q ≠ 0, from λ hq0, hqd0 $ by rw [hq0, nat_degree_zero],
st                                                                       
1992      calc coeff (p.comp q) (nat_degree p * nat_degree q)
1993          = leading_coeff p * leading_coeff q ^ nat_degree p :
1994        coeff_comp_degree_mul_degree hqd0
1995      ... ≠ 0 : mul_ne_zero (mt leading_coeff_eq_zero.1 hp0)
1996        (pow_ne_zero _ (mt leading_coeff_eq_zero.1 hq0)))
1997  
1998  lemma leading_coeff_comp (hq : nat_degree q ≠ 0) : leading_coeff (p.comp q) =
1999    leading_coeff p * leading_coeff q ^ nat_degree p :=
2000  by rw [← coeff_comp_degree_mul_degree hq, ← nat_degree_comp]; refl
id                                                                 └──┘
src                                                                └──┘
typ                                                                └──┘
doc                                                                └──┘
2001  
2002  lemma degree_eq_zero_of_is_unit (h : is_unit p) : degree p = 0 :=
2003  let ⟨q, hq⟩ := is_unit_iff_dvd_one.1 h in
2004  have hp0 : p ≠ 0, from λ hp0, by simpa [hp0] using hq,
2005  have hq0 : q ≠ 0, from λ hp0, by simpa [hp0] using hq,
2006  have nat_degree (1 : polynomial α) = nat_degree (p * q),
id                                   
typ                                  
2007    from congr_arg _ hq,
2008  by rw [nat_degree_one, nat_degree_mul_eq hp0 hq0, eq_comm,
2009      _root_.add_eq_zero_iff, ← with_bot.coe_eq_coe,
2010      ← degree_eq_nat_degree hp0] at this;
2011    exact this.1
2012  
2013  @[simp] lemma degree_coe_units (u : units (polynomial α)) :
id                                                         
typ                                                        
doc    └──┘
2014    degree (u : polynomial α) = 0 :=
id                            
typ                           
2015  degree_eq_zero_of_is_unit ⟨u, rfl⟩
2016  
2017  @[simp] lemma nat_degree_coe_units (u : units (polynomial α)) :
id                                                             
typ                                                            
doc    └──┘
2018    nat_degree (u : polynomial α) = 0 :=
id                                
typ                               
2019  nat_degree_eq_of_degree_eq_some (degree_coe_units u)
2020  
2021  lemma coeff_coe_units_zero_ne_zero (u : units (polynomial α)) :
id                                                             
typ                                                            
2022    coeff (u : polynomial α) 0 ≠ 0 :=
id                           
typ                          
2023  begin
2024    conv in (0) {rw [← nat_degree_coe_units u]},
2025    rw [← leading_coeff, ne.def, leading_coeff_eq_zero],
2026    exact units.coe_ne_zero _
2027  end
st   └─┘
2028  
2029  lemma degree_eq_degree_of_associated (h : associated p q) : degree p = degree q :=
2030  let ⟨u, hu⟩ := h in by simp [hu.symm]
2031  
2032  lemma degree_eq_one_of_irreducible_of_root (hi : irreducible p) {x : α} (hx : is_root p x) :
id                                                                                          
typ                                                                                         
2033    degree p = 1 :=
2034  let ⟨g, hg⟩ := dvd_iff_is_root.2 hx in
2035  have is_unit (X - C x) ∨ is_unit g, from hi.2 _ _ hg,
id                         
src                         
typ                        
2036  this.elim
2037    (λ h, have h₁ : degree (X - C x) = 1, from degree_X_sub_C x,
id                                                              
typ                                                             
2038      have h₂ : degree (X - C x) = 0, from degree_eq_zero_of_is_unit h,
id                               
typ                              
2039      by rw h₁ at h₂; exact absurd h₂ dec_trivial)
2040    (λ hgu, by rw [hg, degree_mul_eq, degree_X_sub_C, degree_eq_zero_of_is_unit hgu, add_zero])
st                                                                                              
2041  
2042  end integral_domain
2043  
2044  section field
2045  variables [discrete_field α] {p q : polynomial α}
id              └┘  └──┘  └──┘
src             └┘  └──┘  └──┘
typ             └┘  └──┘  └──┘
2046  instance : vector_space α (polynomial α) := finsupp.vector_space _ _
id                                        
typ                                       
2047  
2048  lemma is_unit_iff_degree_eq_zero : is_unit p ↔ degree p = 0 :=
id                                                
src                                               
typ                                               
2049  ⟨degree_eq_zero_of_is_unit,
2050    λ h, have degree p ≤ 0, by simp [*, le_refl],
2051      have hc : coeff p 0 ≠ 0, from λ hc,
2052          by rw [eq_C_of_degree_le_zero this, hc] at h;
2053          simpa using h,
2054      is_unit_iff_dvd_one.2 ⟨C (coeff p 0)⁻¹, begin
2055        conv in p { rw eq_C_of_degree_le_zero this },
2056        rw [← C_mul, _root_.mul_inv_cancel hc, C_1]
st                                                   
2057      end⟩⟩
st       └─┘
2058  
2059  lemma degree_pos_of_ne_zero_of_nonunit (hp0 : p ≠ 0) (hp : ¬is_unit p) :
id                                                              
src                                                             
typ                                                             
2060    0 < degree p :=
2061  lt_of_not_ge (λ h, by rw [eq_C_of_degree_le_zero h] at hp0 hp;
2062    exact (hp $ is_unit.map' C $
2063      is_unit.mk0 (coeff p 0) (mt C_inj.2 (by simpa using hp0))))
2064  
2065  lemma irreducible_of_degree_eq_one (hp1 : degree p = 1) : irreducible p :=
2066  ⟨mt is_unit_iff_dvd_one.1 (λ ⟨q, hq⟩,
2067    absurd (congr_arg degree hq) (λ h,
2068      have degree q = 0, by rw [degree_one, degree_mul_eq, hp1, eq_comm,
2069        nat.with_bot.add_eq_zero_iff] at h; exact h.2,
2070      by simp [degree_mul_eq, this, degree_one, hp1] at h;
2071        exact absurd h dec_trivial)),
2072  λ q r hpqr, begin
2073    have := congr_arg degree hpqr,
2074    rw [hp1, degree_mul_eq, eq_comm, nat.with_bot.add_eq_one_iff] at this,
2075    rw [is_unit_iff_degree_eq_zero, is_unit_iff_degree_eq_zero]; tautology
2076  end⟩
st   └─┘
2077  
2078  lemma monic_mul_leading_coeff_inv (h : p ≠ 0) :
2079    monic (p * C (leading_coeff p)⁻¹) :=
2080  by rw [monic, leading_coeff_mul, leading_coeff_C,
2081    mul_inv_cancel (show leading_coeff p ≠ 0, from mt leading_coeff_eq_zero.1 h)]
st                                                                                 
2082  
2083  lemma degree_mul_leading_coeff_inv (p : polynomial α) (h : q ≠ 0) :
id                                                      
typ                                                     
2084    degree (p * C (leading_coeff q)⁻¹) = degree p :=
2085  have h₁ : (leading_coeff q)⁻¹ ≠ 0 :=
2086    inv_ne_zero (mt leading_coeff_eq_zero.1 h),
2087  by rw [degree_mul_eq, degree_C h₁, add_zero]
st                                              
2088  
2089  def div (p q : polynomial α) :=
id                             
typ                            
2090  C (leading_coeff q)⁻¹ * (p /ₘ (q * C (leading_coeff q)⁻¹))
2091  
2092  def mod (p q : polynomial α) :=
id                             
typ                            
2093  p %ₘ (q * C (leading_coeff q)⁻¹)
2094  
2095  private lemma quotient_mul_add_remainder_eq_aux (p q : polynomial α) :
id                                                                     
typ                                                                    
2096    q * div p q + mod p q = p :=
2097  if h : q = 0 then by simp only [h, zero_mul, mod, mod_by_monic_zero, zero_add]
2098  else begin
2099    conv {to_rhs, rw ← mod_by_monic_add_div p (monic_mul_leading_coeff_inv h)},
2100    rw [div, mod, add_comm, mul_assoc]
st                                      
2101  end
2102  
2103  private lemma remainder_lt_aux (p : polynomial α) (hq : q ≠ 0) :
id                                                  
typ                                                 
2104    degree (mod p q) < degree q :=
2105  by rw ← degree_mul_leading_coeff_inv q hq; exact
2106    degree_mod_by_monic_lt p (monic_mul_leading_coeff_inv hq)
2107      (mul_ne_zero hq (mt leading_coeff_eq_zero.2 (by rw leading_coeff_C;
2108        exact inv_ne_zero (mt leading_coeff_eq_zero.1 hq))))
2109  
2110  instance : has_div (polynomial α) := ⟨div⟩
id              └┘  └┘              
src             └┘  └┘
typ             └┘  └┘              
2111  
2112  instance : has_mod (polynomial α) := ⟨mod⟩
id                └┘               
src               └┘  
typ               └┘               
2113  
2114  lemma div_def : p / q = C (leading_coeff q)⁻¹ * (p /ₘ (q * C (leading_coeff q)⁻¹)) := rfl
2115  
2116  lemma mod_def : p % q = p %ₘ (q * C (leading_coeff q)⁻¹) := rfl
2117  
2118  lemma mod_by_monic_eq_mod (p : polynomial α) (hq : monic q) : p %ₘ q = p % q :=
id                                             
typ                                            
2119  show p %ₘ q = p %ₘ (q * C (leading_coeff q)⁻¹), by simp only [monic.def.1 hq, inv_one, mul_one, C_1]
2120  
2121  lemma div_by_monic_eq_div (p : polynomial α) (hq : monic q) : p /ₘ q = p / q :=
id                                             
typ                                            
2122  show p /ₘ q = C (leading_coeff q)⁻¹ * (p /ₘ (q * C (leading_coeff q)⁻¹)),
2123  by simp only [monic.def.1 hq, inv_one, C_1, one_mul, mul_one]
2124  
2125  lemma mod_X_sub_C_eq_C_eval (p : polynomial α) (a : α) : p % (X - C a) = C (p.eval a) :=
id                                                                                   
typ                                                                                  
2126  mod_by_monic_eq_mod p (monic_X_sub_C a) ▸ mod_by_monic_X_sub_C_eq_C_eval _ _
id                                        
typ                                       
2127  
2128  lemma mul_div_eq_iff_is_root : (X - C a) * (p / (X - C a)) = p ↔ is_root p a :=
id                                                                           
src                                                                 
typ                                                                          
2129  div_by_monic_eq_div p (monic_X_sub_C a) ▸ mul_div_by_monic_eq_iff_is_root
id                                        
typ                                       
2130  
2131  instance : euclidean_domain (polynomial α) :=
id              └┘  └┘  └┘  └┘               
src             └┘  └┘  └┘  └┘
typ             └┘  └┘  └┘  └┘               
2132  { quotient := (/),
2133    quotient_zero := by simp [div_def],
2134    remainder := (%),
2135    r := _,
2136    r_well_founded := degree_lt_wf,
2137    quotient_mul_add_remainder_eq := quotient_mul_add_remainder_eq_aux,
2138    remainder_lt := λ p q hq, remainder_lt_aux _ hq,
2139    mul_left_not_lt := λ p q hq, not_lt_of_ge (degree_le_mul_left _ hq) }
2140  
2141  lemma mod_eq_self_iff (hq0 : q ≠ 0) : p % q = p ↔ degree p < degree q :=
id                                                   
src                                                  
typ                                                  
2142  ⟨λ h, h ▸ euclidean_domain.mod_lt _ hq0,
2143  λ h, have ¬degree (q * C (leading_coeff q)⁻¹) ≤ degree p :=
2144    not_le_of_gt $ by rwa degree_mul_leading_coeff_inv q hq0,
2145  begin
2146    rw [mod_def, mod_by_monic, dif_pos (monic_mul_leading_coeff_inv hq0)],
2147    unfold div_mod_by_monic_aux,
2148    simp only [this, false_and, if_false]
2149  end⟩
st   └─┘
2150  
2151  lemma div_eq_zero_iff (hq0 : q ≠ 0) : p / q = 0 ↔ degree p < degree q :=
id                                                   
src                                                  
typ                                                  
2152  ⟨λ h, by have := euclidean_domain.div_add_mod p q;
2153    rwa [h, mul_zero, zero_add, mod_eq_self_iff hq0] at this,
2154  λ h, have hlt : degree p < degree (q * C (leading_coeff q)⁻¹),
2155      by rwa degree_mul_leading_coeff_inv q hq0,
2156    have hm : monic (q * C (leading_coeff q)⁻¹) := monic_mul_leading_coeff_inv hq0,
2157    by rw [div_def, (div_by_monic_eq_zero_iff hm (ne_zero_of_monic hm)).2 hlt, mul_zero]⟩
st                                                                                        
2158  
2159  lemma degree_add_div (hq0 : q ≠ 0) (hpq : degree q ≤ degree p) :
2160    degree q + degree (p / q) = degree p :=
2161  have degree (p % q) < degree (q * (p / q)) :=
2162    calc degree (p % q) < degree q : euclidean_domain.mod_lt _ hq0
2163    ... ≤ _ : degree_le_mul_left _ (mt (div_eq_zero_iff hq0).1 (not_lt_of_ge hpq)),
2164  by conv {to_rhs, rw [← euclidean_domain.div_add_mod p q, add_comm,
2165      degree_add_eq_of_degree_lt this, degree_mul_eq]}
2166  
2167  lemma degree_div_le (p q : polynomial α) : degree (p / q) ≤ degree p :=
id                                         
typ                                        
2168  if hq : q = 0 then by simp [hq]
2169  else by rw [div_def, mul_comm, degree_mul_leading_coeff_inv _ hq];
2170    exact degree_div_by_monic_le _ _
2171  
2172  lemma degree_div_lt (hp : p ≠ 0) (hq : 0 < degree q) : degree (p / q) < degree p :=
2173  have hq0 : q ≠ 0, from λ hq0, by simpa [hq0] using hq,
2174  by rw [div_def, mul_comm, degree_mul_leading_coeff_inv _ hq0];
2175    exact degree_div_by_monic_lt _ (monic_mul_leading_coeff_inv hq0) hp
2176      (by rw degree_mul_leading_coeff_inv _ hq0; exact hq)
2177  
2178  @[simp] lemma degree_map [discrete_field β] (p : polynomial α) (f : α → β) [is_ring_hom f] :
id                             └──┘  └──┘  └┘                                            
src                            └──┘  └──┘  └┘
typ                            └──┘  └──┘  └┘                                            
doc    └──┘
2179    degree (p.map f) = degree p :=
id                   
typ                  
2180  p.degree_map_eq_of_injective (is_ring_hom.injective f)
id                                                       
typ                                                      
2181  
2182  @[simp] lemma nat_degree_map [discrete_field β] (f : α → β) [is_ring_hom f] :
id                                   └──┘  └──┘                            
src                                  └──┘  └──┘
typ                                  └──┘  └──┘                            
doc    └──┘
2183    nat_degree (p.map f) = nat_degree p :=
id                       
typ                      
2184  nat_degree_eq_of_degree_eq (degree_map _ f)
id                                            
typ                                           
2185  
2186  @[simp] lemma leading_coeff_map [discrete_field β] (f : α → β) [is_ring_hom f] :
id                                    └──┘  └──┘  └┘                          
src                                   └──┘  └──┘  └┘
typ                                   └──┘  └──┘  └┘                          
doc    └──┘
2187    leading_coeff (p.map f) = f (leading_coeff p) :=
id                              
typ                             
2188  by simp [leading_coeff, coeff_map f]
id                                     
typ                                    
2189  
2190  lemma map_div [discrete_field β] (f : α → β) [is_ring_hom f] :
id                  └──┘  └──┘  └┘                          
src                 └──┘  └──┘  └┘
typ                 └──┘  └──┘  └┘                          
2191    (p / q).map f = p.map f / q.map f :=
id                                   
typ                                  
2192  if hq0 : q = 0 then by simp [hq0]
2193  else
2194  by rw [div_def, div_def, map_mul, map_div_by_monic f (monic_mul_leading_coeff_inv hq0)];
id                                                      
typ                                                     
2195    simp [is_ring_hom.map_inv f, leading_coeff, coeff_map f]
id                                                          
typ                                                         
2196  
2197  lemma map_mod [discrete_field β] (f : α → β) [is_ring_hom f] :
id                  └──┘  └──┘  └┘                          
src                 └──┘  └──┘  └┘
typ                 └──┘  └──┘  └┘                          
2198    (p % q).map f = p.map f % q.map f :=
id                                   
typ                                  
2199  if hq0 : q = 0 then by simp [hq0]
2200  else by rw [mod_def, mod_def, leading_coeff_map f, ← is_ring_hom.map_inv f, ← map_C f,
id                                                                                     
typ                                                                                    
2201    ← map_mul f, map_mod_by_monic f (monic_mul_leading_coeff_inv hq0)]
id                                  
typ                                 
st                                                                      
2202  
2203  @[simp] lemma map_eq_zero [discrete_field β] (f : α → β) [is_ring_hom f] :
id                              └──┘  └──┘  └┘                          
src                             └──┘  └──┘  └┘
typ                             └──┘  └──┘  └┘                          
doc    └──┘
2204    p.map f = 0 ↔ p = 0 :=
id                
src                
typ               
2205  by simp [polynomial.ext_iff, is_ring_hom.map_eq_zero f, coeff_map]
id                                                        
typ                                                       
2206  
2207  lemma exists_root_of_degree_eq_one (h : degree p = 1) : ∃ x, is_root p x :=
id                                                                         
typ                                                                        
2208  ⟨-(p.coeff 0 / p.coeff 1),
2209    have p.coeff 1 ≠ 0,
2210      by rw ← nat_degree_eq_of_degree_eq_some h;
2211      exact mt leading_coeff_eq_zero.1 (λ h0, by simpa [h0] using h),
2212    by conv in p { rw [eq_X_add_C_of_degree_le_one (show degree p ≤ 1, by rw h; exact le_refl _)] };
2213      simp [is_root, mul_div_cancel' _ this]⟩
2214  
2215  lemma coeff_inv_units (u : units (polynomial α)) (n : ℕ) :
id                                                        
src                                                        
typ                                                       
2216    ((↑u : polynomial α).coeff n)⁻¹ = ((↑u⁻¹ : polynomial α).coeff n) :=
id                                                                 
typ                                                                
2217  begin
2218    rw [eq_C_of_degree_eq_zero (degree_coe_units u), eq_C_of_degree_eq_zero (degree_coe_units u⁻¹),
2219      coeff_C, coeff_C, inv_eq_one_div],
2220    split_ifs,
2221    { rw [div_eq_iff_mul_eq (coeff_coe_units_zero_ne_zero u), coeff_zero_eq_eval_zero,
2222        coeff_zero_eq_eval_zero, ← eval_mul, ← units.coe_mul, inv_mul_self];
2223      simp },
st            └┘
2224    { simp }
st            └─
2225  end
st   ──┘
2226  
2227  instance : normalization_domain (polynomial α) :=
id              └┘  └┘  └┘  └┘  └┘               
src             └┘  └┘  └┘  └┘  └┘
typ             └┘  └┘  └┘  └┘  └┘               
doc             └┘  └┘  └┘  └┘  └┘
2228  { norm_unit := λ p, if hp0 : p = 0 then 1
2229      else ⟨C p.leading_coeff⁻¹, C p.leading_coeff,
2230        by rw [← C_mul, inv_mul_cancel, C_1];
2231         exact mt leading_coeff_eq_zero.1 hp0,
2232        by rw [← C_mul, mul_inv_cancel, C_1];
2233         exact mt leading_coeff_eq_zero.1 hp0,⟩,
2234    norm_unit_zero := dif_pos rfl,
2235    norm_unit_mul := λ p q hp0 hq0, begin
2236        rw [dif_neg hp0, dif_neg hq0, dif_neg (mul_ne_zero hp0 hq0)],
2237        apply units.ext,
2238        show C (leading_coeff (p * q))⁻¹ = C (leading_coeff p)⁻¹ * C (leading_coeff q)⁻¹,
2239        rw [leading_coeff_mul, mul_inv', C_mul, mul_comm]
st                                                         
2240      end,
st       └─┘
2241    norm_unit_coe_units := λ u,
2242      have hu : degree ↑u⁻¹ = 0, from degree_eq_zero_of_is_unit ⟨u⁻¹, rfl⟩,
2243      begin
2244        apply units.ext,
2245        rw [dif_neg (units.coe_ne_zero u)],
2246        conv_rhs {rw eq_C_of_degree_eq_zero hu},
2247        refine C_inj.2 _,
2248        rw [← nat_degree_eq_of_degree_eq_some hu, leading_coeff,
2249          coeff_inv_units],
2250        simp
2251      end,
st       └─┘
2252    ..polynomial.integral_domain }
2253  
2254  lemma monic_normalize (hp0 : p ≠ 0) : monic (normalize p) :=
2255  show leading_coeff (p * ↑(dite _ _ _)) = 1,
2256  by rw dif_neg hp0; exact monic_mul_leading_coeff_inv hp0
2257  
2258  lemma coe_norm_unit (hp : p ≠ 0) : (norm_unit p : polynomial α) = C p.leading_coeff⁻¹ :=
id                                                                
typ                                                               
2259  show ↑(dite _ _ _) = C p.leading_coeff⁻¹, by rw dif_neg hp; refl
id                                                               └──┘
src                                                              └──┘
typ                                                              └──┘
doc                                                              └──┘
2260  
2261  end field
2262  
2263  section derivative
2264  variables [comm_semiring α]
id              └───┘ └┘ └┘ 
src             └───┘ └┘ └┘ 
typ             └───┘ └┘ └┘ 
2265  
2266  /-- `derivative p` formal derivative of the polynomial `p` -/
2267  def derivative (p : polynomial α) : polynomial α := p.sum (λn a, C (a * n) * X^(n - 1))
id                                                                            
typ                                                                           
2268  
2269  lemma coeff_derivative (p : polynomial α) (n : ℕ) : coeff (derivative p) n = coeff p (n + 1) * (n + 1) :=
id                                                                                             
src                                                 
typ                                                                                            
2270  begin
2271    rw [derivative],
2272    simp only [coeff_X_pow, coeff_sum, coeff_C_mul],
2273    rw [finsupp.sum, finset.sum_eq_single (n + 1), apply_eq_coeff],
id                                            
typ                                           
2274    { rw [if_pos (nat.add_sub_cancel _ _).symm, mul_one, nat.cast_add, nat.cast_one] },
st                                                                                     └┘
2275    { assume b, cases b,
id                       
typ                      
2276      { intros, rw [nat.cast_zero, mul_zero, zero_mul] },
st                                                       └┘
2277      { intros _ H, rw [nat.succ_sub_one b, if_neg (mt (congr_arg nat.succ) H.symm), mul_zero] } },
id                                                                  └──────┘
src                                                                  └──────┘
typ                                                                 └──────┘
st                                                                                               └──┘
2278    { intro H, rw [not_mem_support_iff.1 H, zero_mul, zero_mul] }
st                                                                └─
2279  end
st   ──┘
2280  
2281  @[simp] lemma derivative_zero : derivative (0 : polynomial α) = 0 :=
id                                                              
typ                                                             
doc    └──┘
2282  finsupp.sum_zero_index
2283  
2284  lemma derivative_monomial (a : α) (n : ℕ) : derivative (C a * X ^ n) = C (a * n) * X^(n - 1) :=
id                                                                                   
src                                         
typ                                                                                  
2285  by rw [← single_eq_C_mul_X, ← single_eq_C_mul_X, derivative, sum_single_index, single_eq_C_mul_X];
2286    simp only [zero_mul, C_0]; refl
id                                └──┘
src                               └──┘
typ                               └──┘
doc                               └──┘
2287  
2288  @[simp] lemma derivative_C {a : α} : derivative (C a) = 0 :=
id                                                     
typ                                                    
doc    └──┘
2289  suffices derivative (C a * X^0) = C (a * 0:α) * X ^ 0,
id                                            
typ                                           
2290    by simpa only [mul_one, zero_mul, C_0, mul_zero, pow_zero],
2291  derivative_monomial a 0
id                       
typ                      
2292  
2293  @[simp] lemma derivative_X : derivative (X : polynomial α) = 1 :=
id                                                           
typ                                                          
doc    └──┘
2294  suffices derivative (C (1:α) * X^1) = C (1 * (1:ℕ)) * X ^ 0,
id                                                  
src                                                  
typ                                                 
2295    by simpa only [mul_one, one_mul, C_1, pow_one, nat.cast_one, pow_zero],
2296  derivative_monomial 1 1
2297  
2298  @[simp] lemma derivative_one : derivative (1 : polynomial α) = 0 :=
id                                                             
typ                                                            
doc    └──┘
2299  derivative_C
2300  
2301  @[simp] lemma derivative_add {f g : polynomial α} :
id                                                  
typ                                                 
doc    └──┘
2302    derivative (f + g) = derivative f + derivative g :=
id                                                 
typ                                                
2303  by refine finsupp.sum_add_index _ _; intros;
2304  simp only [add_mul, zero_mul, C_0, C_add, C_mul]
2305  
2306  instance : is_add_monoid_hom (derivative : polynomial α → polynomial α) :=
id                                                                       
typ                                                                      
2307  { map_add := λ _ _, derivative_add, map_zero := derivative_zero }
id                  
typ                 
2308  
2309  @[simp] lemma derivative_sum {s : finset β} {f : β → polynomial α} :
id                                       └┘                        
src                                      └┘
typ                                      └┘                        
doc    └──┘                              └┘
2310    derivative (s.sum f) = s.sum (λb, derivative (f b)) :=
id                                                
typ                                               
2311  (s.sum_hom derivative).symm
id    
typ   
2312  
2313  @[simp] lemma derivative_mul {f g : polynomial α} :
id                                                  
typ                                                 
doc    └──┘
2314    derivative (f * g) = derivative f * g + f * derivative g :=
id                                                       
typ                                                      
2315  calc derivative (f * g) = f.sum (λn a, g.sum (λm b, C ((a * b) * (n + m : ℕ)) * X^((n + m) - 1))) :
id                                                                               
src                                                                            
typ                                                                              
2316    begin
2317      transitivity, exact derivative_sum,
2318      transitivity, { apply finset.sum_congr rfl, assume x hx, exact derivative_sum },
st                                                                                     └┘
2319      apply finset.sum_congr rfl, assume n hn, apply finset.sum_congr rfl, assume m hm,
2320      transitivity,
2321      { apply congr_arg, exact single_eq_C_mul_X },
st                                                  └┘
2322      exact derivative_monomial _ _
2323    end
st     └─┘
2324    ... = f.sum (λn a, g.sum (λm b,
id                               
typ                              
2325        (C (a * n) * X^(n - 1)) * (C b * X^m) + (C a * X^n) * (C (b * m) * X^(m - 1)))) :
id                                                                      
typ                                                                     
2326      sum_congr rfl $ assume n hn, sum_congr rfl $ assume m hm,
id                                                          
typ                                                         
2327        by simp only [nat.cast_add, mul_add, add_mul, C_add, C_mul];
2328        cases n; simp only [nat.succ_sub_succ, pow_zero];
id               
typ              
2329        cases m; simp only [nat.cast_zero, C_0, nat.succ_sub_succ, zero_mul, mul_zero,
id               
typ              
2330          nat.sub_zero, pow_zero, pow_add, one_mul, pow_succ, mul_comm, mul_left_comm]
2331    ... = derivative f * g + f * derivative g :
id                                          
typ                                         
2332      begin
2333        conv { to_rhs, congr,
2334          { rw [← sum_C_mul_X_eq g] },
id                                  
typ                                 
2335          { rw [← sum_C_mul_X_eq f] } },
id                                  
typ                                 
st                                       └┘
2336        unfold derivative finsupp.sum,
2337        simp only [sum_add_distrib, finset.mul_sum, finset.sum_mul]
2338      end
st       └─┘
2339  
2340  lemma derivative_eval (p : polynomial α) (x : α) : p.derivative.eval x = p.sum (λ n a, (a * n)*x^(n-1)) :=
id                                                                                           
typ                                                                                          
2341  by simp [derivative, eval_sum, eval_pow]
2342  
2343  end derivative
2344  
2345  section domain
2346  variables [integral_domain α]
id              └───┘ └┘ └┘ └┘
src             └───┘ └┘ └┘ └┘
typ             └───┘ └┘ └┘ └┘
2347  
2348  lemma mem_support_derivative [char_zero α] (p : polynomial α) (n : ℕ) :
id                                                                    
src                                                                     
typ                                                                   
2349    n ∈ (derivative p).support ↔ n + 1 ∈ p.support :=
id                                
src                               
typ                               
2350  suffices (¬(coeff p (n + 1) = 0 ∨ ((n + 1:ℕ) : α) = 0)) ↔ coeff p (n + 1) ≠ 0,
id                                                               
src                                                       
typ                                                              
2351    by simpa only [coeff_derivative, apply_eq_coeff, mem_support_iff, ne.def, mul_eq_zero],
2352  by rw [nat.cast_eq_zero]; simp only [nat.succ_ne_zero, or_false]
2353  
2354  @[simp] lemma degree_derivative_eq [char_zero α] (p : polynomial α) (hp : 0 < nat_degree p) :
id                                                                   
typ                                                                  
doc    └──┘
2355    degree (derivative p) = (nat_degree p - 1 : ℕ) :=
id                                                 
src                                                
typ                                                
2356  le_antisymm
2357    (le_trans (degree_sum_le _ _) $ sup_le $ assume n hn,
id                                                     
typ                                                    
2358      have n ≤ nat_degree p, begin
id            
typ           
2359        rw [← with_bot.coe_le_coe, ← degree_eq_nat_degree],
2360        { refine le_degree_of_ne_zero _, simpa only [mem_support_iff] using hn },
st                                                                                └┘
2361        { assume h, simpa only [h, support_zero] using hn }
st                                                           └┘
2362      end,
st       └─┘
2363      le_trans (degree_monomial_le _ _) $ with_bot.coe_le_coe.2 $ nat.sub_le_sub_right this _)
2364    begin
2365      refine le_sup _,
2366      rw [mem_support_derivative, nat.sub_add_cancel, mem_support_iff],
2367      { show ¬ leading_coeff p = 0,
2368        rw [leading_coeff_eq_zero],
2369        assume h, rw [h, nat_degree_zero] at hp,
2370        exact lt_irrefl 0 (lt_of_le_of_lt (zero_le _) hp), },
st                                                            └┘
2371      exact hp
2372    end
st     └─┘
2373  
2374  end domain
2375  
2376  section identities
2377  
2378  /- @TODO: pow_add_expansion and pow_sub_pow_factor are not specific to polynomials.
2379    These belong somewhere else. But not in group_power because they depend on tactic.ring
2380  
2381  Maybe use data.nat.choose to prove it.
2382   -/
2383  
2384  def pow_add_expansion {α : Type*} [comm_semiring α] (x y : α) : ∀ (n : ℕ),
id                                      └┘  └──┘  └─┘                     
src                                     └┘  └──┘  └─┘                       
typ                                     └┘  └──┘  └─┘                     
2385    {k // (x + y)^n = x^n + n*x^(n-1)*y + k * y^2}
id                                    
typ                                   
2386  | 0 := ⟨0, by simp⟩
2387  | 1 := ⟨0, by simp⟩
2388  | (n+2) :=
2389    begin
2390      cases pow_add_expansion (n+1) with z hz,
id                                
typ                               
2391      existsi x*z + (n+1)*x^n+z*y,
id                              
typ                             
2392      calc (x + y) ^ (n + 2) = (x + y) * (x + y) ^ (n + 1) : by ring_exp
id                                                   
typ                                                  
2393      ... = (x + y) * (x ^ (n + 1) + ↑(n + 1) * x ^ (n + 1 - 1) * y + z * y ^ 2) : by rw hz
2394      ... = x ^ (n + 2) + ↑(n + 2) * x ^ (n + 1) * y + (x*z + (n+1)*x^n+z*y) * y ^ 2 :
id                                                                         
typ                                                                        
2395        by { push_cast, ring_exp! }
st                                   └┘
2396    end
st     └─┘
2397  
2398  variables [comm_ring α]
id              └──┘  └─┘
src             └──┘  └─┘
typ             └──┘  └─┘
2399  
2400  private def poly_binom_aux1 (x y : α) (e : ℕ) (a : α) :
id                                                    
src                                             
typ                                                   
2401    {k : α // a * (x + y)^e = a * (x^e + e*x^(e-1)*y + k*y^2)} :=
id                                             
typ                                            
2402  begin
2403    existsi (pow_add_expansion x y e).val,
2404    congr,
2405    apply (pow_add_expansion _ _ _).property
2406  end
st   └─┘
2407  
2408  private lemma poly_binom_aux2 (f : polynomial α) (x y : α) :
id                                                          
typ                                                         
2409    f.eval (x + y) = f.sum (λ e a, a * (x^e + e*x^(e-1)*y + (poly_binom_aux1 x y e a).val*y^2)) :=
id                                                                            
typ                                                                           
2410  begin
2411    unfold eval eval₂, congr, ext,
2412    apply (poly_binom_aux1 x y _ _).property
id                             
typ                            
2413  end
st   └─┘
2414  
2415  private lemma poly_binom_aux3 (f : polynomial α) (x y : α) : f.eval (x + y) =
id                                                                         
typ                                                                        
2416    f.sum (λ e a, a * x^e) +
id                     
typ                    
2417    f.sum (λ e a, (a * e * x^(e-1)) * y) +
id                                 
typ                                
2418    f.sum (λ e a, (a *(poly_binom_aux1 x y e a).val)*y^2) :=
id                                               
typ                                              
2419  by rw poly_binom_aux2; simp [left_distrib, finsupp.sum_add, mul_assoc]
2420  
2421  def binom_expansion (f : polynomial α) (x y : α) :
id                                                
typ                                               
2422    {k : α // f.eval (x + y) = f.eval x + (f.derivative.eval x) * y + k * y^2} :=
id                                                                    
typ                                                                   
2423  begin
2424    existsi f.sum (λ e a, a *((poly_binom_aux1 x y e a).val)),
2425    rw poly_binom_aux3,
2426    congr,
2427    { rw derivative_eval, symmetry,
2428      apply finsupp.sum_mul },
st                             └┘
2429    { symmetry, apply finsupp.sum_mul }
st                                       └─
2430  end
st   ──┘
2431  
2432  def pow_sub_pow_factor (x y : α) : Π {i : ℕ},{z : α // x^i - y^i = z*(x - y)}
id                                                                    
src                                            
typ                                                                   
2433  | 0 := ⟨0, by simp⟩
2434  | 1 := ⟨1, by simp⟩
2435  | (k+2) :=
2436    begin
2437      cases @pow_sub_pow_factor (k+1) with z hz,
id                                  
typ                                 
2438      existsi z*x + y^(k+1),
id                     
typ                    
2439      calc x ^ (k + 2) - y ^ (k + 2)
2440          = x * (x ^ (k + 1) - y ^ (k + 1)) + (x * y ^ (k + 1) - y ^ (k + 2)) : by ring_exp
id                                                                     
typ                                                                    
2441      ... = x * (z * (x - y)) + (x * y ^ (k + 1) - y ^ (k + 2)) : by rw hz
2442      ... = (z * x + y ^ (k + 1)) * (x - y) : by ring_exp
id              
typ             
2443    end
st     └─┘
2444  
2445  def eval_sub_factor (f : polynomial α) (x y : α) :
id                                                
typ                                               
2446    {z : α // f.eval x - f.eval y = z*(x - y)} :=
id                                       
typ                                      
2447  begin
2448    existsi f.sum (λ a b, b * (pow_sub_pow_factor x y).val),
2449    unfold eval eval₂,
2450    rw [←finsupp.sum_sub],
2451    have : finsupp.sum f (λ (a : ℕ) (b : α), b * (pow_sub_pow_factor x y).val) * (x - y) =
2452      finsupp.sum f (λ (a : ℕ) (b : α), b * (pow_sub_pow_factor x y).val * (x - y)),
id                                                                               
typ                                                                              
2453    { apply finsupp.sum_mul },
st                             └┘
2454    rw this,
2455    congr, ext e a,
2456    rw [mul_assoc, ←(pow_sub_pow_factor x y).property],
id                                          
typ                                         
2457    simp [left_distrib]
2458  end
st   └─┘
2459  
2460  end identities
2461  
2462  end polynomial